Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: chrome/renderer/autofill/form_autocomplete_browsertest.cc

Issue 2007473004: [Autofill] Migrate ContentAutofillDriver<-->AutofillAgent IPCs to mojo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase only Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <tuple> 5 #include <tuple>
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "base/time/time.h" 8 #include "base/time/time.h"
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "chrome/test/base/chrome_render_view_test.h" 10 #include "chrome/test/base/chrome_render_view_test.h"
11 #include "components/autofill/content/common/autofill_messages.h" 11 #include "components/autofill/content/common/autofill_messages.h"
12 #include "components/autofill/content/renderer/autofill_agent.h" 12 #include "components/autofill/content/renderer/autofill_agent.h"
13 #include "components/autofill/core/common/form_data.h" 13 #include "components/autofill/core/common/form_data.h"
14 #include "content/public/test/mock_render_thread.h" 14 #include "content/public/renderer/render_frame.h"
15 #include "content/public/renderer/render_view.h"
16 #include "mojo/public/cpp/bindings/binding_set.h"
17 #include "services/shell/public/cpp/interface_provider.h"
15 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/web/WebDocument.h" 19 #include "third_party/WebKit/public/web/WebDocument.h"
17 #include "third_party/WebKit/public/web/WebElement.h" 20 #include "third_party/WebKit/public/web/WebElement.h"
18 #include "third_party/WebKit/public/web/WebFormElement.h" 21 #include "third_party/WebKit/public/web/WebFormElement.h"
19 #include "third_party/WebKit/public/web/WebInputElement.h" 22 #include "third_party/WebKit/public/web/WebInputElement.h"
20 #include "third_party/WebKit/public/web/WebLocalFrame.h" 23 #include "third_party/WebKit/public/web/WebLocalFrame.h"
21 24
22 using blink::WebDocument; 25 using blink::WebDocument;
23 using blink::WebElement; 26 using blink::WebElement;
24 using blink::WebInputElement; 27 using blink::WebInputElement;
25 using blink::WebString; 28 using blink::WebString;
26 29
27 typedef ChromeRenderViewTest FormAutocompleteTest;
28
29 namespace autofill { 30 namespace autofill {
30 31
31 namespace { 32 namespace {
32 33
34 class FakeContentAutofillDriver : public mojom::AutofillDriver {
35 public:
36 FakeContentAutofillDriver() : called_nofocus_(false) {}
37
38 ~FakeContentAutofillDriver() override {}
39
40 void BindRequest(mojom::AutofillDriverRequest request) {
41 bindings_.AddBinding(this, std::move(request));
42 }
43
44 bool GetCalledNoFocus() const { return called_nofocus_; }
45
46 const FormData* GetFormWillSubmit() const { return form_willsubmit_.get(); }
47
48 const FormData* GetFormSubmitted() const { return form_submitted_.get(); }
49
50 private:
51 // mojom::AutofillDriver:
52 void FirstUserGestureObserved() override {}
53
54 void FormsSeen(mojo::Array<FormData> forms,
55 const base::TimeTicks& timestamp) override {}
56
57 void WillSubmitForm(const FormData& form,
58 const base::TimeTicks& timestamp) override {
59 form_willsubmit_.reset(new FormData(form));
60 }
61
62 void FormSubmitted(const FormData& form) override {
63 form_submitted_.reset(new FormData(form));
64 }
65
66 void TextFieldDidChange(const FormData& form,
67 const FormFieldData& field,
68 const base::TimeTicks& timestamp) override {}
69
70 void QueryFormFieldAutofill(int32_t id,
71 const FormData& form,
72 const FormFieldData& field,
73 const gfx::RectF& bounding_box) override {}
74
75 void HidePopup() override {}
76
77 void PingAck() override {}
78
79 void FocusNoLongerOnForm() override { called_nofocus_ = true; }
80
81 void DidFillAutofillFormData(const FormData& form,
82 const base::TimeTicks& timestamp) override {}
83
84 void DidPreviewAutofillFormData() override {}
85
86 void DidEndTextFieldEditing() override {}
87
88 void SetDataList(mojo::Array<mojo::String> values,
89 mojo::Array<mojo::String> labels) override {}
90
91 // Records whether FocusNoLongerOnForm() get called.
92 bool called_nofocus_;
93 // Records the form data received via WillSubmitForm() call.
94 std::unique_ptr<FormData> form_willsubmit_;
95 // Records the form data received via FormSubmitted() call.
96 std::unique_ptr<FormData> form_submitted_;
97
98 mojo::BindingSet<mojom::AutofillDriver> bindings_;
99 };
100
33 // Helper function to verify the form-related messages received from the 101 // Helper function to verify the form-related messages received from the
34 // renderer. The same data is expected in both messages. Depending on 102 // renderer. The same data is expected in both messages. Depending on
35 // |expect_submitted_message|, will verify presence of FormSubmitted message. 103 // |expect_submitted_message|, will verify presence of FormSubmitted message.
36 void VerifyReceivedRendererMessages(content::MockRenderThread* render_thread, 104 void VerifyReceivedRendererMessages(
37 const std::string& fname, 105 const FakeContentAutofillDriver& fake_driver,
38 const std::string& lname, 106 const std::string& fname,
39 bool expect_submitted_message) { 107 const std::string& lname,
40 const IPC::Message* will_submit_message = 108 bool expect_submitted_message) {
41 render_thread->sink().GetFirstMessageMatching( 109 ASSERT_TRUE(fake_driver.GetFormWillSubmit());
42 AutofillHostMsg_WillSubmitForm::ID); 110 ASSERT_EQ(expect_submitted_message,
43 const IPC::Message* submitted_message = 111 fake_driver.GetFormSubmitted() != nullptr);
44 render_thread->sink().GetFirstMessageMatching(
45 AutofillHostMsg_FormSubmitted::ID);
46 ASSERT_TRUE(will_submit_message != NULL);
47 ASSERT_EQ(expect_submitted_message, submitted_message != NULL);
48 112
49 // The tuple also includes a timestamp, which is ignored. 113 // The tuple also includes a timestamp, which is ignored.
50 std::tuple<FormData, base::TimeTicks> will_submit_forms; 114 const FormData& will_submit_form = *(fake_driver.GetFormWillSubmit());
51 AutofillHostMsg_WillSubmitForm::Read(will_submit_message, &will_submit_forms); 115 ASSERT_LE(2U, will_submit_form.fields.size());
52 ASSERT_LE(2U, std::get<0>(will_submit_forms).fields.size());
53 116
54 FormFieldData& will_submit_form_field = 117 EXPECT_EQ(WebString("fname"), will_submit_form.fields[0].name);
55 std::get<0>(will_submit_forms).fields[0]; 118 EXPECT_EQ(WebString(base::UTF8ToUTF16(fname)),
56 EXPECT_EQ(WebString("fname"), will_submit_form_field.name); 119 will_submit_form.fields[0].value);
57 EXPECT_EQ(WebString(base::UTF8ToUTF16(fname)), will_submit_form_field.value); 120 EXPECT_EQ(WebString("lname"), will_submit_form.fields[1].name);
58 will_submit_form_field = std::get<0>(will_submit_forms).fields[1]; 121 EXPECT_EQ(WebString(base::UTF8ToUTF16(lname)),
59 EXPECT_EQ(WebString("lname"), will_submit_form_field.name); 122 will_submit_form.fields[1].value);
60 EXPECT_EQ(WebString(base::UTF8ToUTF16(lname)), will_submit_form_field.value);
61 123
62 if (expect_submitted_message) { 124 if (expect_submitted_message) {
63 std::tuple<FormData> submitted_forms; 125 const FormData& submitted_form = *(fake_driver.GetFormSubmitted());
64 AutofillHostMsg_FormSubmitted::Read(submitted_message, &submitted_forms); 126 ASSERT_LE(2U, submitted_form.fields.size());
65 ASSERT_LE(2U, std::get<0>(submitted_forms).fields.size());
66 127
67 FormFieldData& submitted_field = std::get<0>(submitted_forms).fields[0]; 128 EXPECT_EQ(WebString("fname"), submitted_form.fields[0].name);
68 EXPECT_EQ(WebString("fname"), submitted_field.name); 129 EXPECT_EQ(WebString(base::UTF8ToUTF16(fname)),
69 EXPECT_EQ(WebString(base::UTF8ToUTF16(fname)), submitted_field.value); 130 submitted_form.fields[0].value);
70 submitted_field = std::get<0>(submitted_forms).fields[1]; 131 EXPECT_EQ(WebString("lname"), submitted_form.fields[1].name);
71 EXPECT_EQ(WebString("lname"), submitted_field.name); 132 EXPECT_EQ(WebString(base::UTF8ToUTF16(lname)),
72 EXPECT_EQ(WebString(base::UTF8ToUTF16(lname)), submitted_field.value); 133 submitted_form.fields[1].value);
73 } 134 }
74 } 135 }
75 136
76 // Helper function to verify that NO form-related messages are received from the 137 // Helper function to verify that NO form-related messages are received from the
77 // renderer. 138 // renderer.
78 void VerifyNoSubmitMessagesReceived(content::MockRenderThread* render_thread) { 139 void VerifyNoSubmitMessagesReceived(
140 const FakeContentAutofillDriver& fake_driver) {
79 // No submission messages sent. 141 // No submission messages sent.
80 const IPC::Message* will_submit_message = 142 EXPECT_EQ(nullptr, fake_driver.GetFormWillSubmit());
81 render_thread->sink().GetFirstMessageMatching( 143 EXPECT_EQ(nullptr, fake_driver.GetFormSubmitted());
82 AutofillHostMsg_WillSubmitForm::ID);
83 const IPC::Message* submitted_message =
84 render_thread->sink().GetFirstMessageMatching(
85 AutofillHostMsg_FormSubmitted::ID);
86 EXPECT_EQ(NULL, will_submit_message);
87 EXPECT_EQ(NULL, submitted_message);
88 } 144 }
89 145
90 // Simulates receiving a message from the browser to fill a form. 146 // Simulates receiving a message from the browser to fill a form.
91 void SimulateOnFillForm(content::MockRenderThread* render_thread, 147 void SimulateOnFillForm(autofill::AutofillAgent* autofill_agent,
92 autofill::AutofillAgent* autofill_agent,
93 blink::WebFrame* main_frame) { 148 blink::WebFrame* main_frame) {
94 WebDocument document = main_frame->document(); 149 WebDocument document = main_frame->document();
95 WebElement element = 150 WebElement element =
96 document.getElementById(WebString::fromUTF8("fname")); 151 document.getElementById(WebString::fromUTF8("fname"));
97 ASSERT_FALSE(element.isNull()); 152 ASSERT_FALSE(element.isNull());
98 153
99 // This call is necessary to setup the autofill agent appropriate for the 154 // This call is necessary to setup the autofill agent appropriate for the
100 // user selection; simulates the menu actually popping up. 155 // user selection; simulates the menu actually popping up.
101 render_thread->sink().ClearMessages();
102 static_cast<autofill::PageClickListener*>(autofill_agent) 156 static_cast<autofill::PageClickListener*>(autofill_agent)
103 ->FormControlElementClicked(element.to<WebInputElement>(), false); 157 ->FormControlElementClicked(element.to<WebInputElement>(), false);
104 158
105 FormData data; 159 FormData data;
106 data.name = base::ASCIIToUTF16("name"); 160 data.name = base::ASCIIToUTF16("name");
107 data.origin = GURL("http://example.com/"); 161 data.origin = GURL("http://example.com/");
108 data.action = GURL("http://example.com/blade.php"); 162 data.action = GURL("http://example.com/blade.php");
109 data.is_form_tag = true; // Default value. 163 data.is_form_tag = true; // Default value.
110 164
111 FormFieldData field_data; 165 FormFieldData field_data;
112 field_data.name = base::ASCIIToUTF16("fname"); 166 field_data.name = base::ASCIIToUTF16("fname");
113 field_data.value = base::ASCIIToUTF16("John"); 167 field_data.value = base::ASCIIToUTF16("John");
114 field_data.is_autofilled = true; 168 field_data.is_autofilled = true;
115 data.fields.push_back(field_data); 169 data.fields.push_back(field_data);
116 170
117 field_data.name = base::ASCIIToUTF16("lname"); 171 field_data.name = base::ASCIIToUTF16("lname");
118 field_data.value = base::ASCIIToUTF16("Smith"); 172 field_data.value = base::ASCIIToUTF16("Smith");
119 field_data.is_autofilled = true; 173 field_data.is_autofilled = true;
120 data.fields.push_back(field_data); 174 data.fields.push_back(field_data);
121 175
122 AutofillMsg_FillForm msg(0, 0, data); 176 autofill_agent->FillForm(0, data);
123 static_cast<content::RenderFrameObserver*>(autofill_agent)
124 ->OnMessageReceived(msg);
125 } 177 }
126 178
127 } // end namespace 179 } // end namespace
128 180
181 class FormAutocompleteTest : public ChromeRenderViewTest {
182 public:
183 FormAutocompleteTest() {}
184 ~FormAutocompleteTest() override {}
185
186 protected:
187 void SetUp() override {
188 ChromeRenderViewTest::SetUp();
189
190 // We only use the fake driver for main frame
191 // because our test cases only involve the main frame.
192 shell::InterfaceProvider* remote_interfaces =
193 view_->GetMainRenderFrame()->GetRemoteInterfaces();
194 shell::InterfaceProvider::TestApi test_api(remote_interfaces);
195 test_api.SetBinderForName(
196 mojom::AutofillDriver::Name_,
197 base::Bind(&FormAutocompleteTest::BindAutofillDriver,
198 base::Unretained(this)));
199 }
200
201 void BindAutofillDriver(mojo::ScopedMessagePipeHandle handle) {
202 fake_driver_.BindRequest(
203 mojo::MakeRequest<mojom::AutofillDriver>(std::move(handle)));
204 }
205
206 FakeContentAutofillDriver fake_driver_;
207
208 private:
209 DISALLOW_COPY_AND_ASSIGN(FormAutocompleteTest);
210 };
211
129 // Tests that submitting a form generates WillSubmitForm and FormSubmitted 212 // Tests that submitting a form generates WillSubmitForm and FormSubmitted
130 // messages with the form fields. 213 // messages with the form fields.
131 TEST_F(FormAutocompleteTest, NormalFormSubmit) { 214 TEST_F(FormAutocompleteTest, NormalFormSubmit) {
132 // Load a form. 215 // Load a form.
133 LoadHTML("<html><form id='myForm'><input name='fname' value='Rick'/>" 216 LoadHTML("<html><form id='myForm'><input name='fname' value='Rick'/>"
134 "<input name='lname' value='Deckard'/></form></html>"); 217 "<input name='lname' value='Deckard'/></form></html>");
135 218
136 // Submit the form. 219 // Submit the form.
137 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();"); 220 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();");
138 ProcessPendingMessages(); 221 ProcessPendingMessages();
139 222
140 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 223 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
141 true /* expect_submitted_message */); 224 true /* expect_submitted_message */);
142 } 225 }
143 226
144 // Tests that submitting a form that prevents the submit event from propagating 227 // Tests that submitting a form that prevents the submit event from propagating
145 // will only send the WillSubmitForm message. 228 // will only send the WillSubmitForm message.
146 TEST_F(FormAutocompleteTest, SubmitEventPrevented) { 229 TEST_F(FormAutocompleteTest, SubmitEventPrevented) {
147 // Load a form. 230 // Load a form.
148 LoadHTML( 231 LoadHTML(
149 "<html><form id='myForm'><input name='fname' value='Rick'/>" 232 "<html><form id='myForm'><input name='fname' value='Rick'/>"
150 "<input name='lname' value='Deckard'/><input type=submit></form>" 233 "<input name='lname' value='Deckard'/><input type=submit></form>"
151 "</html>"); 234 "</html>");
152 235
153 // Submit the form. 236 // Submit the form.
154 ExecuteJavaScriptForTests( 237 ExecuteJavaScriptForTests(
155 "var form = document.forms[0];" 238 "var form = document.forms[0];"
156 "form.onsubmit = function(event) { event.preventDefault(); };" 239 "form.onsubmit = function(event) { event.preventDefault(); };"
157 "document.querySelector('input[type=submit]').click();"); 240 "document.querySelector('input[type=submit]').click();");
158 ProcessPendingMessages(); 241 ProcessPendingMessages();
159 242
160 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 243 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
161 false /* expect_submitted_message */); 244 false /* expect_submitted_message */);
162 } 245 }
163 246
164 // Tests that completing an Ajax request and having the form disappear will 247 // Tests that completing an Ajax request and having the form disappear will
165 // trigger submission from Autofill's point of view. 248 // trigger submission from Autofill's point of view.
166 TEST_F(FormAutocompleteTest, AjaxSucceeded_NoLongerVisible) { 249 TEST_F(FormAutocompleteTest, AjaxSucceeded_NoLongerVisible) {
167 // Load a form. 250 // Load a form.
168 LoadHTML( 251 LoadHTML(
169 "<html><form id='myForm' action='http://example.com/blade.php'>" 252 "<html><form id='myForm' action='http://example.com/blade.php'>"
170 "<input name='fname' id='fname' value='Bob'/>" 253 "<input name='fname' id='fname' value='Bob'/>"
171 "<input name='lname' value='Deckard'/><input type=submit></form></html>"); 254 "<input name='lname' value='Deckard'/><input type=submit></form></html>");
172 255
173 // Simulate user input so that the form is "remembered". 256 // Simulate user input so that the form is "remembered".
174 WebDocument document = GetMainFrame()->document(); 257 WebDocument document = GetMainFrame()->document();
175 WebElement element = document.getElementById(WebString::fromUTF8("fname")); 258 WebElement element = document.getElementById(WebString::fromUTF8("fname"));
176 ASSERT_FALSE(element.isNull()); 259 ASSERT_FALSE(element.isNull());
177 WebInputElement fname_element = element.to<WebInputElement>(); 260 WebInputElement fname_element = element.to<WebInputElement>();
178 SimulateUserInputChangeForElement(&fname_element, std::string("Rick")); 261 SimulateUserInputChangeForElement(&fname_element, std::string("Rick"));
179 262
180 // Simulate removing the form just before the ajax request completes. 263 // Simulate removing the form just before the ajax request completes.
181 ExecuteJavaScriptForTests( 264 ExecuteJavaScriptForTests(
182 "var element = document.getElementById('myForm');" 265 "var element = document.getElementById('myForm');"
183 "element.parentNode.removeChild(element);"); 266 "element.parentNode.removeChild(element);");
184 267
185 // Simulate an Ajax request completing. 268 // Simulate an Ajax request completing.
186 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 269 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
187 ProcessPendingMessages(); 270 ProcessPendingMessages();
188 271
189 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 272 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
190 true /* expect_submitted_message */); 273 true /* expect_submitted_message */);
191 } 274 }
192 275
193 // Tests that completing an Ajax request and having the form with a specific 276 // Tests that completing an Ajax request and having the form with a specific
194 // action disappear will trigger submission from Autofill's point of view, even 277 // action disappear will trigger submission from Autofill's point of view, even
195 // if there is another form with the same data but different action on the page. 278 // if there is another form with the same data but different action on the page.
196 TEST_F(FormAutocompleteTest, 279 TEST_F(FormAutocompleteTest,
197 AjaxSucceeded_NoLongerVisible_DifferentActionsSameData) { 280 AjaxSucceeded_NoLongerVisible_DifferentActionsSameData) {
198 // Load a form. 281 // Load a form.
199 LoadHTML( 282 LoadHTML(
(...skipping 13 matching lines...) Expand all
213 296
214 // Simulate removing the form just before the ajax request completes. 297 // Simulate removing the form just before the ajax request completes.
215 ExecuteJavaScriptForTests( 298 ExecuteJavaScriptForTests(
216 "var element = document.getElementById('myForm');" 299 "var element = document.getElementById('myForm');"
217 "element.parentNode.removeChild(element);"); 300 "element.parentNode.removeChild(element);");
218 301
219 // Simulate an Ajax request completing. 302 // Simulate an Ajax request completing.
220 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 303 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
221 ProcessPendingMessages(); 304 ProcessPendingMessages();
222 305
223 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 306 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
224 true /* expect_submitted_message */); 307 true /* expect_submitted_message */);
225 } 308 }
226 309
227 // Tests that completing an Ajax request and having the form with no action 310 // Tests that completing an Ajax request and having the form with no action
228 // specified disappear will trigger submission from Autofill's point of view, 311 // specified disappear will trigger submission from Autofill's point of view,
229 // even if there is still another form with no action in the page. It will 312 // even if there is still another form with no action in the page. It will
230 // compare field data within the forms. 313 // compare field data within the forms.
231 // TODO(kolos) Re-enable when the implementation of IsFormVisible is on-par 314 // TODO(kolos) Re-enable when the implementation of IsFormVisible is on-par
232 // for these platforms. 315 // for these platforms.
233 #if defined(OS_MACOSX) || defined(OS_ANDROID) 316 #if defined(OS_MACOSX) || defined(OS_ANDROID)
(...skipping 20 matching lines...) Expand all
254 337
255 // Simulate removing the form just before the ajax request completes. 338 // Simulate removing the form just before the ajax request completes.
256 ExecuteJavaScriptForTests( 339 ExecuteJavaScriptForTests(
257 "var element = document.getElementById('myForm');" 340 "var element = document.getElementById('myForm');"
258 "element.parentNode.removeChild(element);"); 341 "element.parentNode.removeChild(element);");
259 342
260 // Simulate an Ajax request completing. 343 // Simulate an Ajax request completing.
261 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 344 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
262 ProcessPendingMessages(); 345 ProcessPendingMessages();
263 346
264 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 347 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
265 true /* expect_submitted_message */); 348 true /* expect_submitted_message */);
266 } 349 }
267 350
268 // Tests that completing an Ajax request and having the form with no action 351 // Tests that completing an Ajax request and having the form with no action
269 // specified disappear will trigger submission from Autofill's point of view. 352 // specified disappear will trigger submission from Autofill's point of view.
270 TEST_F(FormAutocompleteTest, AjaxSucceeded_NoLongerVisible_NoAction) { 353 TEST_F(FormAutocompleteTest, AjaxSucceeded_NoLongerVisible_NoAction) {
271 // Load a form. 354 // Load a form.
272 LoadHTML( 355 LoadHTML(
273 "<html><form id='myForm'>" 356 "<html><form id='myForm'>"
274 "<input name='fname' id='fname' value='Bob'/>" 357 "<input name='fname' id='fname' value='Bob'/>"
275 "<input name='lname' value='Deckard'/><input type=submit></form></html>"); 358 "<input name='lname' value='Deckard'/><input type=submit></form></html>");
276 359
277 // Simulate user input so that the form is "remembered". 360 // Simulate user input so that the form is "remembered".
278 WebDocument document = GetMainFrame()->document(); 361 WebDocument document = GetMainFrame()->document();
279 WebElement element = 362 WebElement element =
280 document.getElementById(WebString::fromUTF8("fname")); 363 document.getElementById(WebString::fromUTF8("fname"));
281 ASSERT_FALSE(element.isNull()); 364 ASSERT_FALSE(element.isNull());
282 WebInputElement fname_element = element.to<WebInputElement>(); 365 WebInputElement fname_element = element.to<WebInputElement>();
283 SimulateUserInputChangeForElement(&fname_element, std::string("Rick")); 366 SimulateUserInputChangeForElement(&fname_element, std::string("Rick"));
284 367
285 // Simulate removing the form just before the ajax request completes. 368 // Simulate removing the form just before the ajax request completes.
286 ExecuteJavaScriptForTests("var element = document.getElementById('myForm');" 369 ExecuteJavaScriptForTests("var element = document.getElementById('myForm');"
287 "element.parentNode.removeChild(element);"); 370 "element.parentNode.removeChild(element);");
288 371
289 // Simulate an Ajax request completing. 372 // Simulate an Ajax request completing.
290 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 373 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
291 ProcessPendingMessages(); 374 ProcessPendingMessages();
292 375
293 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 376 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
294 true /* expect_submitted_message */); 377 true /* expect_submitted_message */);
295 } 378 }
296 379
297 // Tests that completing an Ajax request but leaving a form visible will not 380 // Tests that completing an Ajax request but leaving a form visible will not
298 // trigger submission from Autofill's point of view. 381 // trigger submission from Autofill's point of view.
299 TEST_F(FormAutocompleteTest, AjaxSucceeded_StillVisible) { 382 TEST_F(FormAutocompleteTest, AjaxSucceeded_StillVisible) {
300 // Load a form. 383 // Load a form.
301 LoadHTML( 384 LoadHTML(
302 "<html><form id='myForm' action='http://example.com/blade.php'>" 385 "<html><form id='myForm' action='http://example.com/blade.php'>"
303 "<input name='fname' id='fname' value='Bob'/>" 386 "<input name='fname' id='fname' value='Bob'/>"
304 "<input name='lname' value='Deckard'/><input type=submit></form></html>"); 387 "<input name='lname' value='Deckard'/><input type=submit></form></html>");
305 388
306 // Simulate user input so that the form is "remembered". 389 // Simulate user input so that the form is "remembered".
307 WebDocument document = GetMainFrame()->document(); 390 WebDocument document = GetMainFrame()->document();
308 WebElement element = 391 WebElement element =
309 document.getElementById(WebString::fromUTF8("fname")); 392 document.getElementById(WebString::fromUTF8("fname"));
310 ASSERT_FALSE(element.isNull()); 393 ASSERT_FALSE(element.isNull());
311 WebInputElement fname_element = element.to<WebInputElement>(); 394 WebInputElement fname_element = element.to<WebInputElement>();
312 SimulateUserInputChangeForElement(&fname_element, std::string("Rick")); 395 SimulateUserInputChangeForElement(&fname_element, std::string("Rick"));
313 396
314 // Simulate an Ajax request completing. 397 // Simulate an Ajax request completing.
315 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 398 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
316 ProcessPendingMessages(); 399 ProcessPendingMessages();
317 400
318 // No submission messages sent. 401 // No submission messages sent.
319 VerifyNoSubmitMessagesReceived(render_thread_.get()); 402 VerifyNoSubmitMessagesReceived(fake_driver_);
320 } 403 }
321 404
322 // Tests that completing an Ajax request without any prior form interaction 405 // Tests that completing an Ajax request without any prior form interaction
323 // does not trigger form submission from Autofill's point of view. 406 // does not trigger form submission from Autofill's point of view.
324 TEST_F(FormAutocompleteTest, AjaxSucceeded_NoFormInteractionInvisible) { 407 TEST_F(FormAutocompleteTest, AjaxSucceeded_NoFormInteractionInvisible) {
325 // Load a form. 408 // Load a form.
326 LoadHTML( 409 LoadHTML(
327 "<html><form id='myForm' action='http://example.com/blade.php'>" 410 "<html><form id='myForm' action='http://example.com/blade.php'>"
328 "<input name='fname' id='fname' value='Bob'/>" 411 "<input name='fname' id='fname' value='Bob'/>"
329 "<input name='lname' value='Deckard'/><input type=submit></form></html>"); 412 "<input name='lname' value='Deckard'/><input type=submit></form></html>");
330 413
331 // No form interaction. 414 // No form interaction.
332 415
333 // Simulate removing the form just before the ajax request completes. 416 // Simulate removing the form just before the ajax request completes.
334 ExecuteJavaScriptForTests("var element = document.getElementById('myForm');" 417 ExecuteJavaScriptForTests("var element = document.getElementById('myForm');"
335 "element.parentNode.removeChild(element);"); 418 "element.parentNode.removeChild(element);");
336 419
337 // Simulate an Ajax request completing without prior user interaction. 420 // Simulate an Ajax request completing without prior user interaction.
338 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 421 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
339 ProcessPendingMessages(); 422 ProcessPendingMessages();
340 423
341 // No submission messages sent. 424 // No submission messages sent.
342 VerifyNoSubmitMessagesReceived(render_thread_.get()); 425 VerifyNoSubmitMessagesReceived(fake_driver_);
343 } 426 }
344 427
345 // Tests that completing an Ajax request after having autofilled a form, 428 // Tests that completing an Ajax request after having autofilled a form,
346 // with the form disappearing, will trigger submission from Autofill's 429 // with the form disappearing, will trigger submission from Autofill's
347 // point of view. 430 // point of view.
348 TEST_F(FormAutocompleteTest, AjaxSucceeded_FilledFormIsInvisible) { 431 TEST_F(FormAutocompleteTest, AjaxSucceeded_FilledFormIsInvisible) {
349 // Load a form. 432 // Load a form.
350 LoadHTML( 433 LoadHTML(
351 "<html><form id='myForm' action='http://example.com/blade.php'>" 434 "<html><form id='myForm' action='http://example.com/blade.php'>"
352 "<input name='fname' id='fname'/>" 435 "<input name='fname' id='fname'/>"
353 "<input name='lname'/></form></html>"); 436 "<input name='lname'/></form></html>");
354 437
355 // Simulate filling a form using Autofill. 438 // Simulate filling a form using Autofill.
356 SimulateOnFillForm(render_thread_.get(), autofill_agent_, GetMainFrame()); 439 SimulateOnFillForm(autofill_agent_, GetMainFrame());
357 440
358 // Simulate removing the form just before the ajax request completes. 441 // Simulate removing the form just before the ajax request completes.
359 ExecuteJavaScriptForTests("var element = document.getElementById('myForm');" 442 ExecuteJavaScriptForTests("var element = document.getElementById('myForm');"
360 "element.parentNode.removeChild(element);"); 443 "element.parentNode.removeChild(element);");
361 444
362 // Simulate an Ajax request completing. 445 // Simulate an Ajax request completing.
363 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 446 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
364 ProcessPendingMessages(); 447 ProcessPendingMessages();
365 448
366 VerifyReceivedRendererMessages(render_thread_.get(), "John", "Smith", 449 VerifyReceivedRendererMessages(fake_driver_, "John", "Smith",
367 true /* expect_submitted_message */); 450 true /* expect_submitted_message */);
368 } 451 }
369 452
370 // Tests that completing an Ajax request after having autofilled a form, 453 // Tests that completing an Ajax request after having autofilled a form,
371 // without the form disappearing, will not trigger submission from Autofill's 454 // without the form disappearing, will not trigger submission from Autofill's
372 // point of view. 455 // point of view.
373 TEST_F(FormAutocompleteTest, AjaxSucceeded_FilledFormStillVisible) { 456 TEST_F(FormAutocompleteTest, AjaxSucceeded_FilledFormStillVisible) {
374 // Load a form. 457 // Load a form.
375 LoadHTML( 458 LoadHTML(
376 "<html><form id='myForm' action='http://example.com/blade.php'>" 459 "<html><form id='myForm' action='http://example.com/blade.php'>"
377 "<input name='fname' id='fname' value='Rick'/>" 460 "<input name='fname' id='fname' value='Rick'/>"
378 "<input name='lname' value='Deckard'/></form></html>"); 461 "<input name='lname' value='Deckard'/></form></html>");
379 462
380 // Simulate filling a form using Autofill. 463 // Simulate filling a form using Autofill.
381 SimulateOnFillForm(render_thread_.get(), autofill_agent_, GetMainFrame()); 464 SimulateOnFillForm(autofill_agent_, GetMainFrame());
382 465
383 // Form still visible. 466 // Form still visible.
384 467
385 // Simulate an Ajax request completing. 468 // Simulate an Ajax request completing.
386 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 469 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
387 ProcessPendingMessages(); 470 ProcessPendingMessages();
388 471
389 // No submission messages sent. 472 // No submission messages sent.
390 VerifyNoSubmitMessagesReceived(render_thread_.get()); 473 VerifyNoSubmitMessagesReceived(fake_driver_);
391 } 474 }
392 475
393 // Tests that completing an Ajax request without a form present will still 476 // Tests that completing an Ajax request without a form present will still
394 // trigger submission, if all the inputs the user has modified disappear. 477 // trigger submission, if all the inputs the user has modified disappear.
395 TEST_F(FormAutocompleteTest, AjaxSucceeded_FormlessElements) { 478 TEST_F(FormAutocompleteTest, AjaxSucceeded_FormlessElements) {
396 // Load a "form." Note that kRequiredFieldsForUpload fields are required 479 // Load a "form." Note that kRequiredFieldsForUpload fields are required
397 // for the formless logic to trigger, so we add a throwaway third field. 480 // for the formless logic to trigger, so we add a throwaway third field.
398 LoadHTML( 481 LoadHTML(
399 "<head><title>Checkout</title></head>" 482 "<head><title>Checkout</title></head>"
400 "<input type='text' name='fname' id='fname'/>" 483 "<input type='text' name='fname' id='fname'/>"
401 "<input type='text' name='lname' value='Puckett'/>" 484 "<input type='text' name='lname' value='Puckett'/>"
402 "<input type='number' name='number' value='34'/>"); 485 "<input type='number' name='number' value='34'/>");
403 486
404 // Simulate user input. 487 // Simulate user input.
405 WebDocument document = GetMainFrame()->document(); 488 WebDocument document = GetMainFrame()->document();
406 WebElement element = document.getElementById(WebString::fromUTF8("fname")); 489 WebElement element = document.getElementById(WebString::fromUTF8("fname"));
407 ASSERT_FALSE(element.isNull()); 490 ASSERT_FALSE(element.isNull());
408 WebInputElement fname_element = element.to<WebInputElement>(); 491 WebInputElement fname_element = element.to<WebInputElement>();
409 SimulateUserInputChangeForElement(&fname_element, std::string("Kirby")); 492 SimulateUserInputChangeForElement(&fname_element, std::string("Kirby"));
410 493
411 // Remove element from view. 494 // Remove element from view.
412 ExecuteJavaScriptForTests( 495 ExecuteJavaScriptForTests(
413 "var element = document.getElementById('fname');" 496 "var element = document.getElementById('fname');"
414 "element.style.display = 'none';"); 497 "element.style.display = 'none';");
415 498
416 // Simulate AJAX request. 499 // Simulate AJAX request.
417 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded(); 500 static_cast<blink::WebAutofillClient*>(autofill_agent_)->ajaxSucceeded();
418 ProcessPendingMessages(); 501 ProcessPendingMessages();
419 502
420 VerifyReceivedRendererMessages(render_thread_.get(), "Kirby", "Puckett", 503 VerifyReceivedRendererMessages(fake_driver_, "Kirby", "Puckett",
421 /* expect_submitted_message = */ true); 504 /* expect_submitted_message = */ true);
422 } 505 }
423 506
424 // Unit test for CollectFormlessElements. 507 // Unit test for CollectFormlessElements.
425 TEST_F(FormAutocompleteTest, CollectFormlessElements) { 508 TEST_F(FormAutocompleteTest, CollectFormlessElements) {
426 LoadHTML( 509 LoadHTML(
427 "<html><title>Checkout</title></head>" 510 "<html><title>Checkout</title></head>"
428 "<input type='text' name='text_input'/>" 511 "<input type='text' name='text_input'/>"
429 "<input type='checkbox' name='check_input'/>" 512 "<input type='checkbox' name='check_input'/>"
430 "<input type='number' name='number_input'/>" 513 "<input type='number' name='number_input'/>"
(...skipping 27 matching lines...) Expand all
458 "<input name='fname' id='fname' value='Bob'/>" 541 "<input name='fname' id='fname' value='Bob'/>"
459 "<input name='lname' value='Deckard'/><input type=submit></form></html>"); 542 "<input name='lname' value='Deckard'/><input type=submit></form></html>");
460 543
461 // Simulate user input so that the form is "remembered". 544 // Simulate user input so that the form is "remembered".
462 WebDocument document = GetMainFrame()->document(); 545 WebDocument document = GetMainFrame()->document();
463 WebElement element = document.getElementById(WebString::fromUTF8("fname")); 546 WebElement element = document.getElementById(WebString::fromUTF8("fname"));
464 ASSERT_FALSE(element.isNull()); 547 ASSERT_FALSE(element.isNull());
465 WebInputElement fname_element = element.to<WebInputElement>(); 548 WebInputElement fname_element = element.to<WebInputElement>();
466 SimulateUserInputChangeForElement(&fname_element, std::string("Rick")); 549 SimulateUserInputChangeForElement(&fname_element, std::string("Rick"));
467 550
551 ASSERT_FALSE(fake_driver_.GetCalledNoFocus());
552
468 // Change focus to a different node outside the form. 553 // Change focus to a different node outside the form.
469 WebElement different = 554 WebElement different =
470 document.getElementById(WebString::fromUTF8("different")); 555 document.getElementById(WebString::fromUTF8("different"));
471 SetFocused(different); 556 SetFocused(different);
472 557
473 ProcessPendingMessages(); 558 base::RunLoop run_loop;
559 run_loop.RunUntilIdle();
474 560
475 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 561 EXPECT_TRUE(fake_driver_.GetCalledNoFocus());
476 AutofillHostMsg_FocusNoLongerOnForm::ID) != nullptr);
477 } 562 }
478 563
479 // Test that a FocusNoLongerOnForm message is sent if focus goes from one 564 // Test that a FocusNoLongerOnForm message is sent if focus goes from one
480 // interacted form to another. 565 // interacted form to another.
481 TEST_F(FormAutocompleteTest, InteractingInDifferentForms_FocusNoLongerOnForm) { 566 TEST_F(FormAutocompleteTest, InteractingInDifferentForms_FocusNoLongerOnForm) {
482 // Load a form. 567 // Load a form.
483 LoadHTML( 568 LoadHTML(
484 "<html><form id='myForm' action='http://example.com/blade.php'>" 569 "<html><form id='myForm' action='http://example.com/blade.php'>"
485 "<input name='fname' id='fname' value='Bob'/>" 570 "<input name='fname' id='fname' value='Bob'/>"
486 "<input name='lname' value='Deckard'/><input type=submit></form>" 571 "<input name='lname' value='Deckard'/><input type=submit></form>"
487 "<form id='myForm2' action='http://example.com/runner.php'>" 572 "<form id='myForm2' action='http://example.com/runner.php'>"
488 "<input name='fname' id='fname2' value='Bob'/>" 573 "<input name='fname' id='fname2' value='Bob'/>"
489 "<input name='lname' value='Deckard'/><input type=submit></form></html>"); 574 "<input name='lname' value='Deckard'/><input type=submit></form></html>");
490 575
491 // Simulate user input in the first form so that the form is "remembered". 576 // Simulate user input in the first form so that the form is "remembered".
492 WebDocument document = GetMainFrame()->document(); 577 WebDocument document = GetMainFrame()->document();
493 WebElement element = document.getElementById(WebString::fromUTF8("fname")); 578 WebElement element = document.getElementById(WebString::fromUTF8("fname"));
494 ASSERT_FALSE(element.isNull()); 579 ASSERT_FALSE(element.isNull());
495 WebInputElement fname_element = element.to<WebInputElement>(); 580 WebInputElement fname_element = element.to<WebInputElement>();
496 SimulateUserInputChangeForElement(&fname_element, std::string("Rick")); 581 SimulateUserInputChangeForElement(&fname_element, std::string("Rick"));
497 582
583 ASSERT_FALSE(fake_driver_.GetCalledNoFocus());
584
498 // Simulate user input in the second form so that a "no longer focused" 585 // Simulate user input in the second form so that a "no longer focused"
499 // message is sent for the first form. 586 // message is sent for the first form.
500 document = GetMainFrame()->document(); 587 document = GetMainFrame()->document();
501 element = document.getElementById(WebString::fromUTF8("fname2")); 588 element = document.getElementById(WebString::fromUTF8("fname2"));
502 ASSERT_FALSE(element.isNull()); 589 ASSERT_FALSE(element.isNull());
503 fname_element = element.to<WebInputElement>(); 590 fname_element = element.to<WebInputElement>();
504 SimulateUserInputChangeForElement(&fname_element, std::string("John")); 591 SimulateUserInputChangeForElement(&fname_element, std::string("John"));
505 592
506 ProcessPendingMessages(); 593 base::RunLoop run_loop;
594 run_loop.RunUntilIdle();
507 595
508 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 596 EXPECT_TRUE(fake_driver_.GetCalledNoFocus());
509 AutofillHostMsg_FocusNoLongerOnForm::ID) != nullptr);
510 } 597 }
511 598
512 // Tests that submitting a form that has autocomplete="off" generates 599 // Tests that submitting a form that has autocomplete="off" generates
513 // WillSubmitForm and FormSubmitted messages. 600 // WillSubmitForm and FormSubmitted messages.
514 TEST_F(FormAutocompleteTest, AutoCompleteOffFormSubmit) { 601 TEST_F(FormAutocompleteTest, AutoCompleteOffFormSubmit) {
515 // Load a form. 602 // Load a form.
516 LoadHTML("<html><form id='myForm' autocomplete='off'>" 603 LoadHTML("<html><form id='myForm' autocomplete='off'>"
517 "<input name='fname' value='Rick'/>" 604 "<input name='fname' value='Rick'/>"
518 "<input name='lname' value='Deckard'/>" 605 "<input name='lname' value='Deckard'/>"
519 "</form></html>"); 606 "</form></html>");
520 607
521 // Submit the form. 608 // Submit the form.
522 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();"); 609 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();");
523 ProcessPendingMessages(); 610 ProcessPendingMessages();
524 611
525 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 612 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
526 true /* expect_submitted_message */); 613 true /* expect_submitted_message */);
527 } 614 }
528 615
529 // Tests that fields with autocomplete off are submitted. 616 // Tests that fields with autocomplete off are submitted.
530 TEST_F(FormAutocompleteTest, AutoCompleteOffInputSubmit) { 617 TEST_F(FormAutocompleteTest, AutoCompleteOffInputSubmit) {
531 // Load a form. 618 // Load a form.
532 LoadHTML("<html><form id='myForm'>" 619 LoadHTML("<html><form id='myForm'>"
533 "<input name='fname' value='Rick'/>" 620 "<input name='fname' value='Rick'/>"
534 "<input name='lname' value='Deckard' autocomplete='off'/>" 621 "<input name='lname' value='Deckard' autocomplete='off'/>"
535 "</form></html>"); 622 "</form></html>");
536 623
537 // Submit the form. 624 // Submit the form.
538 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();"); 625 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();");
539 ProcessPendingMessages(); 626 ProcessPendingMessages();
540 627
541 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 628 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
542 true /* expect_submitted_message */); 629 true /* expect_submitted_message */);
543 } 630 }
544 631
545 // Tests that submitting a form that has been dynamically set as autocomplete 632 // Tests that submitting a form that has been dynamically set as autocomplete
546 // off generates WillSubmitForm and FormSubmitted messages. 633 // off generates WillSubmitForm and FormSubmitted messages.
547 // Note: We previously did the opposite, for bug http://crbug.com/36520 634 // Note: We previously did the opposite, for bug http://crbug.com/36520
548 TEST_F(FormAutocompleteTest, DynamicAutoCompleteOffFormSubmit) { 635 TEST_F(FormAutocompleteTest, DynamicAutoCompleteOffFormSubmit) {
549 LoadHTML("<html><form id='myForm'><input name='fname' value='Rick'/>" 636 LoadHTML("<html><form id='myForm'><input name='fname' value='Rick'/>"
550 "<input name='lname' value='Deckard'/></form></html>"); 637 "<input name='lname' value='Deckard'/></form></html>");
551 638
552 WebElement element = 639 WebElement element =
553 GetMainFrame()->document().getElementById(blink::WebString("myForm")); 640 GetMainFrame()->document().getElementById(blink::WebString("myForm"));
554 ASSERT_FALSE(element.isNull()); 641 ASSERT_FALSE(element.isNull());
555 blink::WebFormElement form = element.to<blink::WebFormElement>(); 642 blink::WebFormElement form = element.to<blink::WebFormElement>();
556 EXPECT_TRUE(form.autoComplete()); 643 EXPECT_TRUE(form.autoComplete());
557 644
558 // Dynamically mark the form as autocomplete off. 645 // Dynamically mark the form as autocomplete off.
559 ExecuteJavaScriptForTests( 646 ExecuteJavaScriptForTests(
560 "document.getElementById('myForm')." 647 "document.getElementById('myForm')."
561 "setAttribute('autocomplete', 'off');"); 648 "setAttribute('autocomplete', 'off');");
562 ProcessPendingMessages(); 649 ProcessPendingMessages();
563 EXPECT_FALSE(form.autoComplete()); 650 EXPECT_FALSE(form.autoComplete());
564 651
565 // Submit the form. 652 // Submit the form.
566 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();"); 653 ExecuteJavaScriptForTests("document.getElementById('myForm').submit();");
567 ProcessPendingMessages(); 654 ProcessPendingMessages();
568 655
569 VerifyReceivedRendererMessages(render_thread_.get(), "Rick", "Deckard", 656 VerifyReceivedRendererMessages(fake_driver_, "Rick", "Deckard",
570 true /* expect_submitted_message */); 657 true /* expect_submitted_message */);
571 } 658 }
572 659
573 } // namespace autofill 660 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698