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

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

Powered by Google App Engine
This is Rietveld 408576698