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

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

Powered by Google App Engine
This is Rietveld 408576698