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

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

Powered by Google App Engine
This is Rietveld 408576698