Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / chrome / renderer / autofill / form_autofill_browsertest.cc
blob76dba7bbba239d7e59bdb14762e704dc99a63a55
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <vector>
7 #include "base/format_macros.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/test/base/chrome_render_view_test.h"
12 #include "components/autofill/content/renderer/form_autofill_util.h"
13 #include "components/autofill/content/renderer/form_cache.h"
14 #include "components/autofill/core/common/autofill_data_validation.h"
15 #include "components/autofill/core/common/form_data.h"
16 #include "components/autofill/core/common/web_element_descriptor.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "third_party/WebKit/public/platform/WebVector.h"
20 #include "third_party/WebKit/public/web/WebDocument.h"
21 #include "third_party/WebKit/public/web/WebElement.h"
22 #include "third_party/WebKit/public/web/WebElementCollection.h"
23 #include "third_party/WebKit/public/web/WebExceptionCode.h"
24 #include "third_party/WebKit/public/web/WebFormControlElement.h"
25 #include "third_party/WebKit/public/web/WebFormElement.h"
26 #include "third_party/WebKit/public/web/WebInputElement.h"
27 #include "third_party/WebKit/public/web/WebLocalFrame.h"
28 #include "third_party/WebKit/public/web/WebSelectElement.h"
29 #include "third_party/WebKit/public/web/WebTextAreaElement.h"
31 using base::ASCIIToUTF16;
32 using blink::WebDocument;
33 using blink::WebElement;
34 using blink::WebExceptionCode;
35 using blink::WebFormControlElement;
36 using blink::WebFormElement;
37 using blink::WebFrame;
38 using blink::WebInputElement;
39 using blink::WebSelectElement;
40 using blink::WebString;
41 using blink::WebTextAreaElement;
42 using blink::WebVector;
44 namespace autofill {
46 namespace {
48 struct AutofillFieldCase {
49 const char* const form_control_type;
50 const char* const name;
51 const char* const initial_value;
52 const char* const autocomplete_attribute; // The autocomplete attribute of
53 // the element.
54 bool should_be_autofilled; // Whether the filed should be autofilled.
55 const char* const autofill_value; // The value being used to fill the field.
56 const char* const expected_value; // The expected value after Autofill
57 // or Preview.
60 const char kFormHtml[] =
61 "<FORM name='TestForm' action='http://buh.com' method='post'>"
62 " <INPUT type='text' id='firstname'/>"
63 " <INPUT type='text' id='lastname'/>"
64 " <INPUT type='hidden' id='imhidden'/>"
65 " <INPUT type='text' id='notempty' value='Hi'/>"
66 " <INPUT type='text' autocomplete='off' id='noautocomplete'/>"
67 " <INPUT type='text' disabled='disabled' id='notenabled'/>"
68 " <INPUT type='text' readonly id='readonly'/>"
69 " <INPUT type='text' style='visibility: hidden'"
70 " id='invisible'/>"
71 " <INPUT type='text' style='display: none' id='displaynone'/>"
72 " <INPUT type='month' id='month'/>"
73 " <INPUT type='month' id='month-nonempty' value='2011-12'/>"
74 " <SELECT id='select'>"
75 " <OPTION></OPTION>"
76 " <OPTION value='CA'>California</OPTION>"
77 " <OPTION value='TX'>Texas</OPTION>"
78 " </SELECT>"
79 " <SELECT id='select-nonempty'>"
80 " <OPTION value='CA' selected>California</OPTION>"
81 " <OPTION value='TX'>Texas</OPTION>"
82 " </SELECT>"
83 " <SELECT id='select-unchanged'>"
84 " <OPTION value='CA' selected>California</OPTION>"
85 " <OPTION value='TX'>Texas</OPTION>"
86 " </SELECT>"
87 " <TEXTAREA id='textarea'></TEXTAREA>"
88 " <TEXTAREA id='textarea-nonempty'>Go&#10;away!</TEXTAREA>"
89 " <INPUT type='submit' name='reply-send' value='Send'/>"
90 "</FORM>";
92 const char kUnownedFormHtml[] =
93 "<HEAD><TITLE>enter shipping info</TITLE></HEAD>"
94 "<INPUT type='text' id='firstname'/>"
95 "<INPUT type='text' id='lastname'/>"
96 "<INPUT type='hidden' id='imhidden'/>"
97 "<INPUT type='text' id='notempty' value='Hi'/>"
98 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>"
99 "<INPUT type='text' disabled='disabled' id='notenabled'/>"
100 "<INPUT type='text' readonly id='readonly'/>"
101 "<INPUT type='text' style='visibility: hidden'"
102 " id='invisible'/>"
103 "<INPUT type='text' style='display: none' id='displaynone'/>"
104 "<INPUT type='month' id='month'/>"
105 "<INPUT type='month' id='month-nonempty' value='2011-12'/>"
106 "<SELECT id='select'>"
107 " <OPTION></OPTION>"
108 " <OPTION value='CA'>California</OPTION>"
109 " <OPTION value='TX'>Texas</OPTION>"
110 "</SELECT>"
111 "<SELECT id='select-nonempty'>"
112 " <OPTION value='CA' selected>California</OPTION>"
113 " <OPTION value='TX'>Texas</OPTION>"
114 "</SELECT>"
115 "<SELECT id='select-unchanged'>"
116 " <OPTION value='CA' selected>California</OPTION>"
117 " <OPTION value='TX'>Texas</OPTION>"
118 "</SELECT>"
119 "<TEXTAREA id='textarea'></TEXTAREA>"
120 "<TEXTAREA id='textarea-nonempty'>Go&#10;away!</TEXTAREA>"
121 "<INPUT type='submit' name='reply-send' value='Send'/>";
123 std::string RetrievalMethodToString(
124 const WebElementDescriptor::RetrievalMethod& method) {
125 switch (method) {
126 case WebElementDescriptor::CSS_SELECTOR:
127 return "CSS_SELECTOR";
128 case WebElementDescriptor::ID:
129 return "ID";
130 case WebElementDescriptor::NONE:
131 return "NONE";
133 NOTREACHED();
134 return "UNKNOWN";
137 bool ClickElement(const WebDocument& document,
138 const WebElementDescriptor& element_descriptor) {
139 WebString web_descriptor = WebString::fromUTF8(element_descriptor.descriptor);
140 blink::WebElement element;
142 switch (element_descriptor.retrieval_method) {
143 case WebElementDescriptor::CSS_SELECTOR: {
144 WebExceptionCode ec = 0;
145 element = document.querySelector(web_descriptor, ec);
146 if (ec)
147 DVLOG(1) << "Query selector failed. Error code: " << ec << ".";
148 break;
150 case WebElementDescriptor::ID:
151 element = document.getElementById(web_descriptor);
152 break;
153 case WebElementDescriptor::NONE:
154 return true;
157 if (element.isNull()) {
158 DVLOG(1) << "Could not find "
159 << element_descriptor.descriptor
160 << " by "
161 << RetrievalMethodToString(element_descriptor.retrieval_method)
162 << ".";
163 return false;
166 element.simulateClick();
167 return true;
170 } // namespace
172 class FormAutofillTest : public ChromeRenderViewTest {
173 public:
174 FormAutofillTest() : ChromeRenderViewTest() {}
175 ~FormAutofillTest() override {}
177 void ExpectLabels(const char* html,
178 const std::vector<base::string16>& labels,
179 const std::vector<base::string16>& names,
180 const std::vector<base::string16>& values) {
181 std::vector<std::string> control_types(labels.size(), "text");
182 ExpectLabelsAndTypes(html, labels, names, values, control_types);
185 void ExpectLabelsAndTypes(const char* html,
186 const std::vector<base::string16>& labels,
187 const std::vector<base::string16>& names,
188 const std::vector<base::string16>& values,
189 const std::vector<std::string>& control_types) {
190 ASSERT_EQ(labels.size(), names.size());
191 ASSERT_EQ(labels.size(), values.size());
192 ASSERT_EQ(labels.size(), control_types.size());
194 LoadHTML(html);
196 WebFrame* web_frame = GetMainFrame();
197 ASSERT_NE(nullptr, web_frame);
199 FormCache form_cache(*web_frame);
200 std::vector<FormData> forms = form_cache.ExtractNewForms();
201 ASSERT_EQ(1U, forms.size());
203 const FormData& form = forms[0];
204 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
205 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
206 EXPECT_EQ(GURL("http://cnn.com"), form.action);
208 const std::vector<FormFieldData>& fields = form.fields;
209 ASSERT_EQ(labels.size(), fields.size());
210 for (size_t i = 0; i < labels.size(); ++i) {
211 int max_length = control_types[i] == "text" ?
212 WebInputElement::defaultMaxLength() : 0;
213 FormFieldData expected;
214 expected.label = labels[i];
215 expected.name = names[i];
216 expected.value = values[i];
217 expected.form_control_type = control_types[i];
218 expected.max_length = max_length;
219 SCOPED_TRACE(base::StringPrintf("i: %" PRIuS, i));
220 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[i]);
224 void ExpectJohnSmithLabels(const char* html) {
225 std::vector<base::string16> labels, names, values;
227 labels.push_back(ASCIIToUTF16("First name:"));
228 names.push_back(ASCIIToUTF16("firstname"));
229 values.push_back(ASCIIToUTF16("John"));
231 labels.push_back(ASCIIToUTF16("Last name:"));
232 names.push_back(ASCIIToUTF16("lastname"));
233 values.push_back(ASCIIToUTF16("Smith"));
235 labels.push_back(ASCIIToUTF16("Email:"));
236 names.push_back(ASCIIToUTF16("email"));
237 values.push_back(ASCIIToUTF16("john@example.com"));
239 ExpectLabels(html, labels, names, values);
242 typedef void (*FillFormFunction)(const FormData& form,
243 const WebFormControlElement& element);
245 typedef WebString (*GetValueFunction)(WebFormControlElement element);
247 // Test FormFillxxx functions.
248 void TestFormFillFunctions(const char* html,
249 bool unowned,
250 const AutofillFieldCase* field_cases,
251 size_t number_of_field_cases,
252 FillFormFunction fill_form_function,
253 GetValueFunction get_value_function) {
254 LoadHTML(html);
256 WebFrame* web_frame = GetMainFrame();
257 ASSERT_NE(nullptr, web_frame);
259 FormCache form_cache(*web_frame);
260 std::vector<FormData> forms = form_cache.ExtractNewForms();
261 ASSERT_EQ(1U, forms.size());
263 // Get the input element we want to find.
264 WebInputElement input_element = GetInputElementById("firstname");
266 // Find the form that contains the input element.
267 FormData form_data;
268 FormFieldData field;
269 EXPECT_TRUE(FindFormAndFieldForFormControlElement(input_element, &form_data,
270 &field));
271 if (!unowned) {
272 EXPECT_EQ(ASCIIToUTF16("TestForm"), form_data.name);
273 EXPECT_EQ(GURL("http://buh.com"), form_data.action);
276 const std::vector<FormFieldData>& fields = form_data.fields;
277 ASSERT_EQ(number_of_field_cases, fields.size());
279 FormFieldData expected;
280 // Verify field's initial value.
281 for (size_t i = 0; i < number_of_field_cases; ++i) {
282 SCOPED_TRACE(base::StringPrintf("Verify initial value for field %s",
283 field_cases[i].name));
284 expected.form_control_type = field_cases[i].form_control_type;
285 expected.max_length =
286 expected.form_control_type == "text" ?
287 WebInputElement::defaultMaxLength() : 0;
288 expected.name = ASCIIToUTF16(field_cases[i].name);
289 expected.value = ASCIIToUTF16(field_cases[i].initial_value);
290 expected.autocomplete_attribute = field_cases[i].autocomplete_attribute;
291 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[i]);
292 // Fill the form_data for the field.
293 form_data.fields[i].value = ASCIIToUTF16(field_cases[i].autofill_value);
294 // Set the is_autofilled property for the field.
295 form_data.fields[i].is_autofilled = field_cases[i].should_be_autofilled;
298 // Autofill the form using the given fill form function.
299 fill_form_function(form_data, input_element);
301 // Validate Autofill or Preview results.
302 for (size_t i = 0; i < number_of_field_cases; ++i) {
303 ValidateFilledField(field_cases[i], get_value_function);
307 // Validate an Autofilled field.
308 void ValidateFilledField(const AutofillFieldCase& field_case,
309 GetValueFunction get_value_function) {
310 SCOPED_TRACE(base::StringPrintf("Verify autofilled value for field %s",
311 field_case.name));
312 WebString value;
313 WebFormControlElement element =
314 GetFormControlElementById(ASCIIToUTF16(field_case.name));
315 if ((element.formControlType() == "select-one") ||
316 (element.formControlType() == "textarea")) {
317 value = get_value_function(element);
318 } else {
319 ASSERT_TRUE(element.formControlType() == "text" ||
320 element.formControlType() == "month");
321 value = get_value_function(element);
324 const WebString expected_value = ASCIIToUTF16(field_case.expected_value);
325 if (expected_value.isEmpty())
326 EXPECT_TRUE(value.isEmpty());
327 else
328 EXPECT_EQ(expected_value.utf8(), value.utf8());
330 EXPECT_EQ(field_case.should_be_autofilled, element.isAutofilled());
333 WebFormControlElement GetFormControlElementById(const WebString& id) {
334 return GetMainFrame()->document().getElementById(
335 id).to<WebFormControlElement>();
338 WebInputElement GetInputElementById(const WebString& id) {
339 return GetMainFrame()->document().getElementById(
340 id).to<WebInputElement>();
343 void TestFillForm(const char* html, bool unowned) {
344 static const AutofillFieldCase field_cases[] = {
345 // fields: form_control_type, name, initial_value, autocomplete_attribute,
346 // should_be_autofilled, autofill_value, expected_value
348 // Regular empty fields (firstname & lastname) should be autofilled.
349 {"text",
350 "firstname",
353 true,
354 "filled firstname",
355 "filled firstname"},
356 {"text", "lastname", "", "", true, "filled lastname", "filled lastname"},
357 // hidden fields should not be extracted to form_data.
358 // Non empty fields should not be autofilled.
359 {"text", "notempty", "Hi", "", false, "filled notempty", "Hi"},
360 {"text",
361 "noautocomplete",
363 "off",
364 true,
365 "filled noautocomplete",
366 "filled noautocomplete"},
367 // Disabled fields should not be autofilled.
368 {"text", "notenabled", "", "", false, "filled notenabled", ""},
369 // Readonly fields should not be autofilled.
370 {"text", "readonly", "", "", false, "filled readonly", ""},
371 // Fields with "visibility: hidden" should not be autofilled.
372 {"text", "invisible", "", "", false, "filled invisible", ""},
373 // Fields with "display:none" should not be autofilled.
374 {"text", "displaynone", "", "", false, "filled displaynone", ""},
375 // Regular <input type="month"> should be autofilled.
376 {"month", "month", "", "", true, "2017-11", "2017-11"},
377 // Non-empty <input type="month"> should not be autofilled.
378 {"month", "month-nonempty", "2011-12", "", false, "2017-11", "2011-12"},
379 // Regular select fields should be autofilled.
380 {"select-one", "select", "", "", true, "TX", "TX"},
381 // Select fields should be autofilled even if they already have a
382 // non-empty value.
383 {"select-one", "select-nonempty", "CA", "", true, "TX", "TX"},
384 // Select fields should not be autofilled if no new value is passed from
385 // autofill profile. The existing value should not be overriden.
386 {"select-one", "select-unchanged", "CA", "", false, "CA", "CA"},
387 // Regular textarea elements should be autofilled.
388 {"textarea",
389 "textarea",
392 true,
393 "some multi-\nline value",
394 "some multi-\nline value"},
395 // Non-empty textarea elements should not be autofilled.
396 {"textarea",
397 "textarea-nonempty",
398 "Go\naway!",
400 false,
401 "some multi-\nline value",
402 "Go\naway!"},
404 TestFormFillFunctions(html, unowned, field_cases, arraysize(field_cases),
405 FillForm, &GetValueWrapper);
406 // Verify preview selection.
407 WebInputElement firstname = GetInputElementById("firstname");
408 EXPECT_EQ(16, firstname.selectionStart());
409 EXPECT_EQ(16, firstname.selectionEnd());
412 void TestPreviewForm(const char* html, bool unowned) {
413 static const AutofillFieldCase field_cases[] = {
414 // Normal empty fields should be previewed.
415 {"text",
416 "firstname",
419 true,
420 "suggested firstname",
421 "suggested firstname"},
422 {"text",
423 "lastname",
426 true,
427 "suggested lastname",
428 "suggested lastname"},
429 // Hidden fields should not be extracted to form_data.
430 // Non empty fields should not be previewed.
431 {"text", "notempty", "Hi", "", false, "suggested notempty", ""},
432 {"text",
433 "noautocomplete",
435 "off",
436 true,
437 "filled noautocomplete",
438 "filled noautocomplete"},
439 // Disabled fields should not be previewed.
440 {"text", "notenabled", "", "", false, "suggested notenabled", ""},
441 // Readonly fields should not be previewed.
442 {"text", "readonly", "", "", false, "suggested readonly", ""},
443 // Fields with "visibility: hidden" should not be previewed.
444 {"text", "invisible", "", "", false, "suggested invisible", ""},
445 // Fields with "display:none" should not previewed.
446 {"text", "displaynone", "", "", false, "suggested displaynone", ""},
447 // Regular <input type="month"> should be previewed.
448 {"month", "month", "", "", true, "2017-11", "2017-11"},
449 // Non-empty <input type="month"> should not be previewed.
450 {"month", "month-nonempty", "2011-12", "", false, "2017-11", ""},
451 // Regular select fields should be previewed.
452 {"select-one", "select", "", "", true, "TX", "TX"},
453 // Select fields should be previewed even if they already have a
454 // non-empty value.
455 {"select-one", "select-nonempty", "CA", "", true, "TX", "TX"},
456 // Select fields should not be previewed if no suggestion is passed from
457 // autofill profile.
458 {"select-one", "select-unchanged", "CA", "", false, "", ""},
459 // Normal textarea elements should be previewed.
460 {"textarea",
461 "textarea",
464 true,
465 "suggested multi-\nline value",
466 "suggested multi-\nline value"},
467 // Nonempty textarea elements should not be previewed.
468 {"textarea",
469 "textarea-nonempty",
470 "Go\naway!",
472 false,
473 "suggested multi-\nline value",
474 ""},
476 TestFormFillFunctions(html, unowned, field_cases, arraysize(field_cases),
477 &PreviewForm, &GetSuggestedValueWrapper);
479 // Verify preview selection.
480 WebInputElement firstname = GetInputElementById("firstname");
481 EXPECT_EQ(0, firstname.selectionStart());
482 EXPECT_EQ(19, firstname.selectionEnd());
485 void TestFindFormForInputElement(const char* html, bool unowned) {
486 LoadHTML(html);
487 WebFrame* web_frame = GetMainFrame();
488 ASSERT_NE(nullptr, web_frame);
490 FormCache form_cache(*web_frame);
491 std::vector<FormData> forms = form_cache.ExtractNewForms();
492 ASSERT_EQ(1U, forms.size());
494 // Get the input element we want to find.
495 WebInputElement input_element = GetInputElementById("firstname");
497 // Find the form and verify it's the correct form.
498 FormData form;
499 FormFieldData field;
500 EXPECT_TRUE(
501 FindFormAndFieldForFormControlElement(input_element, &form, &field));
502 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
503 if (!unowned) {
504 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
505 EXPECT_EQ(GURL("http://buh.com"), form.action);
508 const std::vector<FormFieldData>& fields = form.fields;
509 ASSERT_EQ(4U, fields.size());
511 FormFieldData expected;
512 expected.form_control_type = "text";
513 expected.max_length = WebInputElement::defaultMaxLength();
515 expected.name = ASCIIToUTF16("firstname");
516 expected.value = ASCIIToUTF16("John");
517 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
518 EXPECT_FORM_FIELD_DATA_EQUALS(expected, field);
520 expected.name = ASCIIToUTF16("lastname");
521 expected.value = ASCIIToUTF16("Smith");
522 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
524 expected.name = ASCIIToUTF16("email");
525 expected.value = ASCIIToUTF16("john@example.com");
526 expected.autocomplete_attribute = "off";
527 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
528 expected.autocomplete_attribute.clear();
530 expected.name = ASCIIToUTF16("phone");
531 expected.value = ASCIIToUTF16("1.800.555.1234");
532 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
535 void TestFindFormForTextAreaElement(const char* html, bool unowned) {
536 LoadHTML(html);
537 WebFrame* web_frame = GetMainFrame();
538 ASSERT_NE(nullptr, web_frame);
540 FormCache form_cache(*web_frame);
541 std::vector<FormData> forms = form_cache.ExtractNewForms();
542 ASSERT_EQ(1U, forms.size());
544 // Get the textarea element we want to find.
545 WebElement element = web_frame->document().getElementById("street-address");
546 WebTextAreaElement textarea_element = element.to<WebTextAreaElement>();
548 // Find the form and verify it's the correct form.
549 FormData form;
550 FormFieldData field;
551 EXPECT_TRUE(
552 FindFormAndFieldForFormControlElement(textarea_element, &form, &field));
553 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
554 if (!unowned) {
555 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
556 EXPECT_EQ(GURL("http://buh.com"), form.action);
559 const std::vector<FormFieldData>& fields = form.fields;
560 ASSERT_EQ(4U, fields.size());
562 FormFieldData expected;
564 expected.name = ASCIIToUTF16("firstname");
565 expected.value = ASCIIToUTF16("John");
566 expected.form_control_type = "text";
567 expected.max_length = WebInputElement::defaultMaxLength();
568 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
570 expected.name = ASCIIToUTF16("lastname");
571 expected.value = ASCIIToUTF16("Smith");
572 expected.form_control_type = "text";
573 expected.max_length = WebInputElement::defaultMaxLength();
574 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
576 expected.name = ASCIIToUTF16("email");
577 expected.value = ASCIIToUTF16("john@example.com");
578 expected.autocomplete_attribute = "off";
579 expected.form_control_type = "text";
580 expected.max_length = WebInputElement::defaultMaxLength();
581 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
582 expected.autocomplete_attribute.clear();
584 expected.name = ASCIIToUTF16("street-address");
585 expected.value = ASCIIToUTF16("123 Fantasy Ln.\nApt. 42");
586 expected.form_control_type = "textarea";
587 expected.max_length = 0;
588 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
589 EXPECT_FORM_FIELD_DATA_EQUALS(expected, field);
592 void TestFillFormMaxLength(const char* html, bool unowned) {
593 LoadHTML(html);
594 WebFrame* web_frame = GetMainFrame();
595 ASSERT_NE(nullptr, web_frame);
597 FormCache form_cache(*web_frame);
598 std::vector<FormData> forms = form_cache.ExtractNewForms();
599 ASSERT_EQ(1U, forms.size());
601 // Get the input element we want to find.
602 WebInputElement input_element = GetInputElementById("firstname");
604 // Find the form that contains the input element.
605 FormData form;
606 FormFieldData field;
607 EXPECT_TRUE(
608 FindFormAndFieldForFormControlElement(input_element, &form, &field));
609 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
610 if (!unowned) {
611 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
612 EXPECT_EQ(GURL("http://buh.com"), form.action);
615 const std::vector<FormFieldData>& fields = form.fields;
616 ASSERT_EQ(3U, fields.size());
618 FormFieldData expected;
619 expected.form_control_type = "text";
621 expected.name = ASCIIToUTF16("firstname");
622 expected.max_length = 5;
623 expected.is_autofilled = false;
624 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
626 expected.name = ASCIIToUTF16("lastname");
627 expected.max_length = 7;
628 expected.is_autofilled = false;
629 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
631 expected.name = ASCIIToUTF16("email");
632 expected.max_length = 9;
633 expected.is_autofilled = false;
634 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
636 // Fill the form.
637 form.fields[0].value = ASCIIToUTF16("Brother");
638 form.fields[1].value = ASCIIToUTF16("Jonathan");
639 form.fields[2].value = ASCIIToUTF16("brotherj@example.com");
640 form.fields[0].is_autofilled = true;
641 form.fields[1].is_autofilled = true;
642 form.fields[2].is_autofilled = true;
643 FillForm(form, input_element);
645 // Find the newly-filled form that contains the input element.
646 FormData form2;
647 FormFieldData field2;
648 EXPECT_TRUE(
649 FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
650 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
651 if (!unowned) {
652 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
653 EXPECT_EQ(GURL("http://buh.com"), form2.action);
656 const std::vector<FormFieldData>& fields2 = form2.fields;
657 ASSERT_EQ(3U, fields2.size());
659 expected.form_control_type = "text";
661 expected.name = ASCIIToUTF16("firstname");
662 expected.value = ASCIIToUTF16("Broth");
663 expected.max_length = 5;
664 expected.is_autofilled = true;
665 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
667 expected.name = ASCIIToUTF16("lastname");
668 expected.value = ASCIIToUTF16("Jonatha");
669 expected.max_length = 7;
670 expected.is_autofilled = true;
671 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
673 expected.name = ASCIIToUTF16("email");
674 expected.value = ASCIIToUTF16("brotherj@");
675 expected.max_length = 9;
676 expected.is_autofilled = true;
677 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
680 void TestFillFormNegativeMaxLength(const char* html, bool unowned) {
681 LoadHTML(html);
682 WebFrame* web_frame = GetMainFrame();
683 ASSERT_NE(nullptr, web_frame);
685 FormCache form_cache(*web_frame);
686 std::vector<FormData> forms = form_cache.ExtractNewForms();
687 ASSERT_EQ(1U, forms.size());
689 // Get the input element we want to find.
690 WebInputElement input_element = GetInputElementById("firstname");
692 // Find the form that contains the input element.
693 FormData form;
694 FormFieldData field;
695 EXPECT_TRUE(
696 FindFormAndFieldForFormControlElement(input_element, &form, &field));
697 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
698 if (!unowned) {
699 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
700 EXPECT_EQ(GURL("http://buh.com"), form.action);
703 const std::vector<FormFieldData>& fields = form.fields;
704 ASSERT_EQ(3U, fields.size());
706 FormFieldData expected;
707 expected.form_control_type = "text";
708 expected.max_length = WebInputElement::defaultMaxLength();
710 expected.name = ASCIIToUTF16("firstname");
711 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
713 expected.name = ASCIIToUTF16("lastname");
714 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
716 expected.name = ASCIIToUTF16("email");
717 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
719 // Fill the form.
720 form.fields[0].value = ASCIIToUTF16("Brother");
721 form.fields[1].value = ASCIIToUTF16("Jonathan");
722 form.fields[2].value = ASCIIToUTF16("brotherj@example.com");
723 FillForm(form, input_element);
725 // Find the newly-filled form that contains the input element.
726 FormData form2;
727 FormFieldData field2;
728 EXPECT_TRUE(
729 FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
730 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
731 if (!unowned) {
732 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
733 EXPECT_EQ(GURL("http://buh.com"), form2.action);
736 const std::vector<FormFieldData>& fields2 = form2.fields;
737 ASSERT_EQ(3U, fields2.size());
739 expected.name = ASCIIToUTF16("firstname");
740 expected.value = ASCIIToUTF16("Brother");
741 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
743 expected.name = ASCIIToUTF16("lastname");
744 expected.value = ASCIIToUTF16("Jonathan");
745 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
747 expected.name = ASCIIToUTF16("email");
748 expected.value = ASCIIToUTF16("brotherj@example.com");
749 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
752 void TestFillFormEmptyName(const char* html, bool unowned) {
753 LoadHTML(html);
754 WebFrame* web_frame = GetMainFrame();
755 ASSERT_NE(nullptr, web_frame);
757 FormCache form_cache(*web_frame);
758 std::vector<FormData> forms = form_cache.ExtractNewForms();
759 ASSERT_EQ(1U, forms.size());
761 // Get the input element we want to find.
762 WebInputElement input_element = GetInputElementById("firstname");
764 // Find the form that contains the input element.
765 FormData form;
766 FormFieldData field;
767 EXPECT_TRUE(
768 FindFormAndFieldForFormControlElement(input_element, &form, &field));
769 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
770 if (!unowned) {
771 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
772 EXPECT_EQ(GURL("http://buh.com"), form.action);
775 const std::vector<FormFieldData>& fields = form.fields;
776 ASSERT_EQ(3U, fields.size());
778 FormFieldData expected;
779 expected.form_control_type = "text";
780 expected.max_length = WebInputElement::defaultMaxLength();
782 expected.name = ASCIIToUTF16("firstname");
783 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
785 expected.name = ASCIIToUTF16("lastname");
786 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
788 expected.name = ASCIIToUTF16("email");
789 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
791 // Fill the form.
792 form.fields[0].value = ASCIIToUTF16("Wyatt");
793 form.fields[1].value = ASCIIToUTF16("Earp");
794 form.fields[2].value = ASCIIToUTF16("wyatt@example.com");
795 FillForm(form, input_element);
797 // Find the newly-filled form that contains the input element.
798 FormData form2;
799 FormFieldData field2;
800 EXPECT_TRUE(
801 FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
802 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
803 if (!unowned) {
804 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
805 EXPECT_EQ(GURL("http://buh.com"), form2.action);
808 const std::vector<FormFieldData>& fields2 = form2.fields;
809 ASSERT_EQ(3U, fields2.size());
811 expected.form_control_type = "text";
812 expected.max_length = WebInputElement::defaultMaxLength();
814 expected.name = ASCIIToUTF16("firstname");
815 expected.value = ASCIIToUTF16("Wyatt");
816 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
818 expected.name = ASCIIToUTF16("lastname");
819 expected.value = ASCIIToUTF16("Earp");
820 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
822 expected.name = ASCIIToUTF16("email");
823 expected.value = ASCIIToUTF16("wyatt@example.com");
824 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
827 void TestFillFormEmptyFormNames(const char* html, bool unowned) {
828 LoadHTML(html);
829 WebFrame* web_frame = GetMainFrame();
830 ASSERT_NE(nullptr, web_frame);
832 FormCache form_cache(*web_frame);
833 std::vector<FormData> forms = form_cache.ExtractNewForms();
834 const size_t expected_size = unowned ? 1 : 2;
835 ASSERT_EQ(expected_size, forms.size());
837 // Get the input element we want to find.
838 WebInputElement input_element = GetInputElementById("apple");
840 // Find the form that contains the input element.
841 FormData form;
842 FormFieldData field;
843 EXPECT_TRUE(
844 FindFormAndFieldForFormControlElement(input_element, &form, &field));
845 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
846 if (!unowned) {
847 EXPECT_TRUE(form.name.empty());
848 EXPECT_EQ(GURL("http://abc.com"), form.action);
851 const std::vector<FormFieldData>& fields = form.fields;
852 const size_t unowned_offset = unowned ? 3 : 0;
853 ASSERT_EQ(unowned_offset + 3, fields.size());
855 FormFieldData expected;
856 expected.form_control_type = "text";
857 expected.max_length = WebInputElement::defaultMaxLength();
859 expected.name = ASCIIToUTF16("apple");
860 expected.is_autofilled = false;
861 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[unowned_offset]);
863 expected.name = ASCIIToUTF16("banana");
864 expected.is_autofilled = false;
865 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[unowned_offset + 1]);
867 expected.name = ASCIIToUTF16("cantelope");
868 expected.is_autofilled = false;
869 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[unowned_offset + 2]);
871 // Fill the form.
872 form.fields[unowned_offset + 0].value = ASCIIToUTF16("Red");
873 form.fields[unowned_offset + 1].value = ASCIIToUTF16("Yellow");
874 form.fields[unowned_offset + 2].value = ASCIIToUTF16("Also Yellow");
875 form.fields[unowned_offset + 0].is_autofilled = true;
876 form.fields[unowned_offset + 1].is_autofilled = true;
877 form.fields[unowned_offset + 2].is_autofilled = true;
878 FillForm(form, input_element);
880 // Find the newly-filled form that contains the input element.
881 FormData form2;
882 FormFieldData field2;
883 EXPECT_TRUE(
884 FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
885 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
886 if (!unowned) {
887 EXPECT_TRUE(form2.name.empty());
888 EXPECT_EQ(GURL("http://abc.com"), form2.action);
891 const std::vector<FormFieldData>& fields2 = form2.fields;
892 ASSERT_EQ(unowned_offset + 3, fields2.size());
894 expected.name = ASCIIToUTF16("apple");
895 expected.value = ASCIIToUTF16("Red");
896 expected.is_autofilled = true;
897 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[unowned_offset + 0]);
899 expected.name = ASCIIToUTF16("banana");
900 expected.value = ASCIIToUTF16("Yellow");
901 expected.is_autofilled = true;
902 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[unowned_offset + 1]);
904 expected.name = ASCIIToUTF16("cantelope");
905 expected.value = ASCIIToUTF16("Also Yellow");
906 expected.is_autofilled = true;
907 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[unowned_offset + 2]);
910 void TestFillFormNonEmptyField(const char* html, bool unowned) {
911 LoadHTML(html);
912 WebFrame* web_frame = GetMainFrame();
913 ASSERT_NE(nullptr, web_frame);
915 FormCache form_cache(*web_frame);
916 std::vector<FormData> forms = form_cache.ExtractNewForms();
917 ASSERT_EQ(1U, forms.size());
919 // Get the input element we want to find.
920 WebInputElement input_element = GetInputElementById("firstname");
922 // Simulate typing by modifying the field value.
923 input_element.setValue(ASCIIToUTF16("Wy"));
925 // Find the form that contains the input element.
926 FormData form;
927 FormFieldData field;
928 EXPECT_TRUE(
929 FindFormAndFieldForFormControlElement(input_element, &form, &field));
930 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
931 if (!unowned) {
932 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
933 EXPECT_EQ(GURL("http://buh.com"), form.action);
936 const std::vector<FormFieldData>& fields = form.fields;
937 ASSERT_EQ(3U, fields.size());
939 FormFieldData expected;
940 expected.form_control_type = "text";
941 expected.max_length = WebInputElement::defaultMaxLength();
943 expected.name = ASCIIToUTF16("firstname");
944 expected.value = ASCIIToUTF16("Wy");
945 expected.is_autofilled = false;
946 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
948 expected.name = ASCIIToUTF16("lastname");
949 expected.value.clear();
950 expected.is_autofilled = false;
951 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
953 expected.name = ASCIIToUTF16("email");
954 expected.value.clear();
955 expected.is_autofilled = false;
956 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
958 // Preview the form and verify that the cursor position has been updated.
959 form.fields[0].value = ASCIIToUTF16("Wyatt");
960 form.fields[1].value = ASCIIToUTF16("Earp");
961 form.fields[2].value = ASCIIToUTF16("wyatt@example.com");
962 form.fields[0].is_autofilled = true;
963 form.fields[1].is_autofilled = true;
964 form.fields[2].is_autofilled = true;
965 PreviewForm(form, input_element);
966 EXPECT_EQ(2, input_element.selectionStart());
967 EXPECT_EQ(5, input_element.selectionEnd());
969 // Fill the form.
970 FillForm(form, input_element);
972 // Find the newly-filled form that contains the input element.
973 FormData form2;
974 FormFieldData field2;
975 EXPECT_TRUE(
976 FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
977 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
978 if (!unowned) {
979 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
980 EXPECT_EQ(GURL("http://buh.com"), form2.action);
983 const std::vector<FormFieldData>& fields2 = form2.fields;
984 ASSERT_EQ(3U, fields2.size());
986 expected.name = ASCIIToUTF16("firstname");
987 expected.value = ASCIIToUTF16("Wyatt");
988 expected.is_autofilled = true;
989 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
991 expected.name = ASCIIToUTF16("lastname");
992 expected.value = ASCIIToUTF16("Earp");
993 expected.is_autofilled = true;
994 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
996 expected.name = ASCIIToUTF16("email");
997 expected.value = ASCIIToUTF16("wyatt@example.com");
998 expected.is_autofilled = true;
999 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
1001 // Verify that the cursor position has been updated.
1002 EXPECT_EQ(5, input_element.selectionStart());
1003 EXPECT_EQ(5, input_element.selectionEnd());
1006 void TestClearFormWithNode(const char* html, bool unowned) {
1007 LoadHTML(html);
1008 WebFrame* web_frame = GetMainFrame();
1009 ASSERT_NE(nullptr, web_frame);
1011 FormCache form_cache(*web_frame);
1012 std::vector<FormData> forms = form_cache.ExtractNewForms();
1013 ASSERT_EQ(1U, forms.size());
1015 // Set the auto-filled attribute.
1016 WebInputElement firstname = GetInputElementById("firstname");
1017 firstname.setAutofilled(true);
1018 WebInputElement lastname = GetInputElementById("lastname");
1019 lastname.setAutofilled(true);
1020 WebInputElement month = GetInputElementById("month");
1021 month.setAutofilled(true);
1022 WebInputElement textarea = GetInputElementById("textarea");
1023 textarea.setAutofilled(true);
1025 // Set the value of the disabled text input element.
1026 WebInputElement notenabled = GetInputElementById("notenabled");
1027 notenabled.setValue(WebString::fromUTF8("no clear"));
1029 // Clear the form.
1030 EXPECT_TRUE(form_cache.ClearFormWithElement(firstname));
1032 // Verify that the auto-filled attribute has been turned off.
1033 EXPECT_FALSE(firstname.isAutofilled());
1035 // Verify the form is cleared.
1036 FormData form;
1037 FormFieldData field;
1038 EXPECT_TRUE(
1039 FindFormAndFieldForFormControlElement(firstname, &form, &field));
1040 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
1041 EXPECT_FALSE(form.origin.is_empty());
1042 if (!unowned) {
1043 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
1044 EXPECT_EQ(GURL("http://buh.com"), form.action);
1047 const std::vector<FormFieldData>& fields = form.fields;
1048 ASSERT_EQ(9U, fields.size());
1050 FormFieldData expected;
1051 expected.form_control_type = "text";
1052 expected.max_length = WebInputElement::defaultMaxLength();
1054 expected.name = ASCIIToUTF16("firstname");
1055 expected.value.clear();
1056 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
1058 expected.name = ASCIIToUTF16("lastname");
1059 expected.value.clear();
1060 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
1062 expected.name = ASCIIToUTF16("noAC");
1063 expected.value = ASCIIToUTF16("one");
1064 expected.autocomplete_attribute = "off";
1065 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
1066 expected.autocomplete_attribute.clear();
1068 expected.name = ASCIIToUTF16("notenabled");
1069 expected.value = ASCIIToUTF16("no clear");
1070 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
1072 expected.form_control_type = "month";
1073 expected.max_length = 0;
1074 expected.name = ASCIIToUTF16("month");
1075 expected.value.clear();
1076 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[4]);
1078 expected.name = ASCIIToUTF16("month-disabled");
1079 expected.value = ASCIIToUTF16("2012-11");
1080 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[5]);
1082 expected.form_control_type = "textarea";
1083 expected.name = ASCIIToUTF16("textarea");
1084 expected.value.clear();
1085 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[6]);
1087 expected.name = ASCIIToUTF16("textarea-disabled");
1088 expected.value = ASCIIToUTF16(" Banana! ");
1089 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[7]);
1091 expected.name = ASCIIToUTF16("textarea-noAC");
1092 expected.value = ASCIIToUTF16("Carrot?");
1093 expected.autocomplete_attribute = "off";
1094 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[8]);
1095 expected.autocomplete_attribute.clear();
1097 // Verify that the cursor position has been updated.
1098 EXPECT_EQ(0, firstname.selectionStart());
1099 EXPECT_EQ(0, firstname.selectionEnd());
1102 void TestClearFormWithNodeContainingSelectOne(const char* html,
1103 bool unowned) {
1104 LoadHTML(html);
1105 WebFrame* web_frame = GetMainFrame();
1106 ASSERT_NE(nullptr, web_frame);
1108 FormCache form_cache(*web_frame);
1109 std::vector<FormData> forms = form_cache.ExtractNewForms();
1110 ASSERT_EQ(1U, forms.size());
1112 // Set the auto-filled attribute.
1113 WebInputElement firstname = GetInputElementById("firstname");
1114 firstname.setAutofilled(true);
1115 WebInputElement lastname = GetInputElementById("lastname");
1116 lastname.setAutofilled(true);
1118 // Set the value and auto-filled attribute of the state element.
1119 WebSelectElement state =
1120 web_frame->document().getElementById("state").to<WebSelectElement>();
1121 state.setValue(WebString::fromUTF8("AK"));
1122 state.setAutofilled(true);
1124 // Clear the form.
1125 EXPECT_TRUE(form_cache.ClearFormWithElement(firstname));
1127 // Verify that the auto-filled attribute has been turned off.
1128 EXPECT_FALSE(firstname.isAutofilled());
1130 // Verify the form is cleared.
1131 FormData form;
1132 FormFieldData field;
1133 EXPECT_TRUE(
1134 FindFormAndFieldForFormControlElement(firstname, &form, &field));
1135 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
1136 EXPECT_FALSE(form.origin.is_empty());
1137 if (!unowned) {
1138 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
1139 EXPECT_EQ(GURL("http://buh.com"), form.action);
1142 const std::vector<FormFieldData>& fields = form.fields;
1143 ASSERT_EQ(3U, fields.size());
1145 FormFieldData expected;
1147 expected.name = ASCIIToUTF16("firstname");
1148 expected.value.clear();
1149 expected.form_control_type = "text";
1150 expected.max_length = WebInputElement::defaultMaxLength();
1151 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
1153 expected.name = ASCIIToUTF16("lastname");
1154 expected.value.clear();
1155 expected.form_control_type = "text";
1156 expected.max_length = WebInputElement::defaultMaxLength();
1157 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
1159 expected.name = ASCIIToUTF16("state");
1160 expected.value = ASCIIToUTF16("?");
1161 expected.form_control_type = "select-one";
1162 expected.max_length = 0;
1163 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
1165 // Verify that the cursor position has been updated.
1166 EXPECT_EQ(0, firstname.selectionStart());
1167 EXPECT_EQ(0, firstname.selectionEnd());
1170 void TestClearPreviewedFormWithElement(const char* html) {
1171 LoadHTML(html);
1172 WebFrame* web_frame = GetMainFrame();
1173 ASSERT_NE(nullptr, web_frame);
1175 FormCache form_cache(*web_frame);
1176 std::vector<FormData> forms = form_cache.ExtractNewForms();
1177 ASSERT_EQ(1U, forms.size());
1179 // Set the auto-filled attribute.
1180 WebInputElement firstname = GetInputElementById("firstname");
1181 firstname.setAutofilled(true);
1182 WebInputElement lastname = GetInputElementById("lastname");
1183 lastname.setAutofilled(true);
1184 WebInputElement email = GetInputElementById("email");
1185 email.setAutofilled(true);
1186 WebInputElement email2 = GetInputElementById("email2");
1187 email2.setAutofilled(true);
1188 WebInputElement phone = GetInputElementById("phone");
1189 phone.setAutofilled(true);
1191 // Set the suggested values on two of the elements.
1192 lastname.setSuggestedValue(ASCIIToUTF16("Earp"));
1193 email.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
1194 email2.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
1195 phone.setSuggestedValue(ASCIIToUTF16("650-777-9999"));
1197 // Clear the previewed fields.
1198 EXPECT_TRUE(ClearPreviewedFormWithElement(lastname, false));
1200 // Fields with empty suggestions suggestions are not modified.
1201 EXPECT_EQ(ASCIIToUTF16("Wyatt"), firstname.value());
1202 EXPECT_TRUE(firstname.suggestedValue().isEmpty());
1203 EXPECT_TRUE(firstname.isAutofilled());
1205 // Verify the previewed fields are cleared.
1206 EXPECT_TRUE(lastname.value().isEmpty());
1207 EXPECT_TRUE(lastname.suggestedValue().isEmpty());
1208 EXPECT_FALSE(lastname.isAutofilled());
1209 EXPECT_TRUE(email.value().isEmpty());
1210 EXPECT_TRUE(email.suggestedValue().isEmpty());
1211 EXPECT_FALSE(email.isAutofilled());
1212 EXPECT_TRUE(email2.value().isEmpty());
1213 EXPECT_TRUE(email2.suggestedValue().isEmpty());
1214 EXPECT_FALSE(email2.isAutofilled());
1215 EXPECT_TRUE(phone.value().isEmpty());
1216 EXPECT_TRUE(phone.suggestedValue().isEmpty());
1217 EXPECT_FALSE(phone.isAutofilled());
1219 // Verify that the cursor position has been updated.
1220 EXPECT_EQ(0, lastname.selectionStart());
1221 EXPECT_EQ(0, lastname.selectionEnd());
1224 void TestClearPreviewedFormWithNonEmptyInitiatingNode(const char* html) {
1225 LoadHTML(html);
1226 WebFrame* web_frame = GetMainFrame();
1227 ASSERT_NE(nullptr, web_frame);
1229 FormCache form_cache(*web_frame);
1230 std::vector<FormData> forms = form_cache.ExtractNewForms();
1231 ASSERT_EQ(1U, forms.size());
1233 // Set the auto-filled attribute.
1234 WebInputElement firstname = GetInputElementById("firstname");
1235 firstname.setAutofilled(true);
1236 WebInputElement lastname = GetInputElementById("lastname");
1237 lastname.setAutofilled(true);
1238 WebInputElement email = GetInputElementById("email");
1239 email.setAutofilled(true);
1240 WebInputElement email2 = GetInputElementById("email2");
1241 email2.setAutofilled(true);
1242 WebInputElement phone = GetInputElementById("phone");
1243 phone.setAutofilled(true);
1246 // Set the suggested values on all of the elements.
1247 firstname.setSuggestedValue(ASCIIToUTF16("Wyatt"));
1248 lastname.setSuggestedValue(ASCIIToUTF16("Earp"));
1249 email.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
1250 email2.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
1251 phone.setSuggestedValue(ASCIIToUTF16("650-777-9999"));
1253 // Clear the previewed fields.
1254 EXPECT_TRUE(ClearPreviewedFormWithElement(firstname, false));
1256 // Fields with non-empty values are restored.
1257 EXPECT_EQ(ASCIIToUTF16("W"), firstname.value());
1258 EXPECT_TRUE(firstname.suggestedValue().isEmpty());
1259 EXPECT_FALSE(firstname.isAutofilled());
1260 EXPECT_EQ(1, firstname.selectionStart());
1261 EXPECT_EQ(1, firstname.selectionEnd());
1263 // Verify the previewed fields are cleared.
1264 EXPECT_TRUE(lastname.value().isEmpty());
1265 EXPECT_TRUE(lastname.suggestedValue().isEmpty());
1266 EXPECT_FALSE(lastname.isAutofilled());
1267 EXPECT_TRUE(email.value().isEmpty());
1268 EXPECT_TRUE(email.suggestedValue().isEmpty());
1269 EXPECT_FALSE(email.isAutofilled());
1270 EXPECT_TRUE(email2.value().isEmpty());
1271 EXPECT_TRUE(email2.suggestedValue().isEmpty());
1272 EXPECT_FALSE(email2.isAutofilled());
1273 EXPECT_TRUE(phone.value().isEmpty());
1274 EXPECT_TRUE(phone.suggestedValue().isEmpty());
1275 EXPECT_FALSE(phone.isAutofilled());
1278 void TestClearPreviewedFormWithAutofilledInitiatingNode(const char* html) {
1279 LoadHTML(html);
1280 WebFrame* web_frame = GetMainFrame();
1281 ASSERT_NE(nullptr, web_frame);
1283 FormCache form_cache(*web_frame);
1284 std::vector<FormData> forms = form_cache.ExtractNewForms();
1285 ASSERT_EQ(1U, forms.size());
1287 // Set the auto-filled attribute.
1288 WebInputElement firstname = GetInputElementById("firstname");
1289 firstname.setAutofilled(true);
1290 WebInputElement lastname = GetInputElementById("lastname");
1291 lastname.setAutofilled(true);
1292 WebInputElement email = GetInputElementById("email");
1293 email.setAutofilled(true);
1294 WebInputElement email2 = GetInputElementById("email2");
1295 email2.setAutofilled(true);
1296 WebInputElement phone = GetInputElementById("phone");
1297 phone.setAutofilled(true);
1299 // Set the suggested values on all of the elements.
1300 firstname.setSuggestedValue(ASCIIToUTF16("Wyatt"));
1301 lastname.setSuggestedValue(ASCIIToUTF16("Earp"));
1302 email.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
1303 email2.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
1304 phone.setSuggestedValue(ASCIIToUTF16("650-777-9999"));
1306 // Clear the previewed fields.
1307 EXPECT_TRUE(ClearPreviewedFormWithElement(firstname, true));
1309 // Fields with non-empty values are restored.
1310 EXPECT_EQ(ASCIIToUTF16("W"), firstname.value());
1311 EXPECT_TRUE(firstname.suggestedValue().isEmpty());
1312 EXPECT_TRUE(firstname.isAutofilled());
1313 EXPECT_EQ(1, firstname.selectionStart());
1314 EXPECT_EQ(1, firstname.selectionEnd());
1316 // Verify the previewed fields are cleared.
1317 EXPECT_TRUE(lastname.value().isEmpty());
1318 EXPECT_TRUE(lastname.suggestedValue().isEmpty());
1319 EXPECT_FALSE(lastname.isAutofilled());
1320 EXPECT_TRUE(email.value().isEmpty());
1321 EXPECT_TRUE(email.suggestedValue().isEmpty());
1322 EXPECT_FALSE(email.isAutofilled());
1323 EXPECT_TRUE(email2.value().isEmpty());
1324 EXPECT_TRUE(email2.suggestedValue().isEmpty());
1325 EXPECT_FALSE(email2.isAutofilled());
1326 EXPECT_TRUE(phone.value().isEmpty());
1327 EXPECT_TRUE(phone.suggestedValue().isEmpty());
1328 EXPECT_FALSE(phone.isAutofilled());
1331 void TestClearOnlyAutofilledFields(const char* html) {
1332 LoadHTML(html);
1334 WebFrame* web_frame = GetMainFrame();
1335 ASSERT_NE(nullptr, web_frame);
1337 FormCache form_cache(*web_frame);
1338 std::vector<FormData> forms = form_cache.ExtractNewForms();
1339 ASSERT_EQ(1U, forms.size());
1341 // Set the autofilled attribute.
1342 WebInputElement firstname = GetInputElementById("firstname");
1343 firstname.setAutofilled(false);
1344 WebInputElement lastname = GetInputElementById("lastname");
1345 lastname.setAutofilled(true);
1346 WebInputElement email = GetInputElementById("email");
1347 email.setAutofilled(true);
1348 WebInputElement phone = GetInputElementById("phone");
1349 phone.setAutofilled(true);
1351 // Clear the fields.
1352 EXPECT_TRUE(form_cache.ClearFormWithElement(firstname));
1354 // Verify only autofilled fields are cleared.
1355 EXPECT_EQ(ASCIIToUTF16("Wyatt"), firstname.value());
1356 EXPECT_TRUE(firstname.suggestedValue().isEmpty());
1357 EXPECT_FALSE(firstname.isAutofilled());
1358 EXPECT_TRUE(lastname.value().isEmpty());
1359 EXPECT_TRUE(lastname.suggestedValue().isEmpty());
1360 EXPECT_FALSE(lastname.isAutofilled());
1361 EXPECT_TRUE(email.value().isEmpty());
1362 EXPECT_TRUE(email.suggestedValue().isEmpty());
1363 EXPECT_FALSE(email.isAutofilled());
1364 EXPECT_TRUE(phone.value().isEmpty());
1365 EXPECT_TRUE(phone.suggestedValue().isEmpty());
1366 EXPECT_FALSE(phone.isAutofilled());
1369 static void FillFormIncludingNonFocusableElementsWrapper(
1370 const FormData& form,
1371 const WebFormControlElement& element) {
1372 FillFormIncludingNonFocusableElements(form, element.form());
1375 static WebString GetValueWrapper(WebFormControlElement element) {
1376 if (element.formControlType() == "textarea")
1377 return element.to<WebTextAreaElement>().value();
1379 if (element.formControlType() == "select-one")
1380 return element.to<WebSelectElement>().value();
1382 return element.to<WebInputElement>().value();
1385 static WebString GetSuggestedValueWrapper(WebFormControlElement element) {
1386 if (element.formControlType() == "textarea")
1387 return element.to<WebTextAreaElement>().suggestedValue();
1389 if (element.formControlType() == "select-one")
1390 return element.to<WebSelectElement>().suggestedValue();
1392 return element.to<WebInputElement>().suggestedValue();
1395 private:
1396 DISALLOW_COPY_AND_ASSIGN(FormAutofillTest);
1399 // We should be able to extract a normal text field.
1400 TEST_F(FormAutofillTest, WebFormControlElementToFormField) {
1401 LoadHTML("<INPUT type='text' id='element' value='value'/>");
1403 WebFrame* frame = GetMainFrame();
1404 ASSERT_NE(nullptr, frame);
1406 WebFormControlElement element = GetFormControlElementById("element");
1407 FormFieldData result1;
1408 WebFormControlElementToFormField(element, EXTRACT_NONE, &result1);
1410 FormFieldData expected;
1411 expected.form_control_type = "text";
1412 expected.max_length = WebInputElement::defaultMaxLength();
1414 expected.name = ASCIIToUTF16("element");
1415 expected.value.clear();
1416 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result1);
1418 FormFieldData result2;
1419 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result2);
1421 expected.name = ASCIIToUTF16("element");
1422 expected.value = ASCIIToUTF16("value");
1423 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result2);
1426 // We should be able to extract a text field with autocomplete="off".
1427 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompleteOff) {
1428 LoadHTML("<INPUT type='text' id='element' value='value'"
1429 " autocomplete='off'/>");
1431 WebFrame* frame = GetMainFrame();
1432 ASSERT_NE(nullptr, frame);
1434 WebFormControlElement element = GetFormControlElementById("element");
1435 FormFieldData result;
1436 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1438 FormFieldData expected;
1439 expected.name = ASCIIToUTF16("element");
1440 expected.value = ASCIIToUTF16("value");
1441 expected.form_control_type = "text";
1442 expected.autocomplete_attribute = "off";
1443 expected.max_length = WebInputElement::defaultMaxLength();
1444 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1447 // We should be able to extract a text field with maxlength specified.
1448 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMaxLength) {
1449 LoadHTML("<INPUT type='text' id='element' value='value'"
1450 " maxlength='5'/>");
1452 WebFrame* frame = GetMainFrame();
1453 ASSERT_NE(nullptr, frame);
1455 WebFormControlElement element = GetFormControlElementById("element");
1456 FormFieldData result;
1457 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1459 FormFieldData expected;
1460 expected.name = ASCIIToUTF16("element");
1461 expected.value = ASCIIToUTF16("value");
1462 expected.form_control_type = "text";
1463 expected.max_length = 5;
1464 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1467 // We should be able to extract a text field that has been autofilled.
1468 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutofilled) {
1469 LoadHTML("<INPUT type='text' id='element' value='value'/>");
1471 WebFrame* frame = GetMainFrame();
1472 ASSERT_NE(nullptr, frame);
1474 WebInputElement element = GetInputElementById("element");
1475 element.setAutofilled(true);
1476 FormFieldData result;
1477 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1479 FormFieldData expected;
1480 expected.name = ASCIIToUTF16("element");
1481 expected.value = ASCIIToUTF16("value");
1482 expected.form_control_type = "text";
1483 expected.max_length = WebInputElement::defaultMaxLength();
1484 expected.is_autofilled = true;
1485 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1488 // We should be able to extract a radio or a checkbox field that has been
1489 // autofilled.
1490 TEST_F(FormAutofillTest, WebFormControlElementToClickableFormField) {
1491 LoadHTML("<INPUT type='checkbox' id='checkbox' value='mail' checked/>"
1492 "<INPUT type='radio' id='radio' value='male'/>");
1494 WebFrame* frame = GetMainFrame();
1495 ASSERT_NE(nullptr, frame);
1497 WebInputElement element = GetInputElementById("checkbox");
1498 element.setAutofilled(true);
1499 FormFieldData result;
1500 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1502 FormFieldData expected;
1503 expected.name = ASCIIToUTF16("checkbox");
1504 expected.value = ASCIIToUTF16("mail");
1505 expected.form_control_type = "checkbox";
1506 expected.is_autofilled = true;
1507 expected.is_checkable = true;
1508 expected.is_checked = true;
1509 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1511 element = GetInputElementById("radio");
1512 element.setAutofilled(true);
1513 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1514 expected.name = ASCIIToUTF16("radio");
1515 expected.value = ASCIIToUTF16("male");
1516 expected.form_control_type = "radio";
1517 expected.is_autofilled = true;
1518 expected.is_checkable = true;
1519 expected.is_checked = false;
1520 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1523 // We should be able to extract a <select> field.
1524 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldSelect) {
1525 LoadHTML("<SELECT id='element'/>"
1526 " <OPTION value='CA'>California</OPTION>"
1527 " <OPTION value='TX'>Texas</OPTION>"
1528 "</SELECT>");
1530 WebFrame* frame = GetMainFrame();
1531 ASSERT_NE(nullptr, frame);
1533 WebFormControlElement element = GetFormControlElementById("element");
1534 FormFieldData result1;
1535 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result1);
1537 FormFieldData expected;
1538 expected.name = ASCIIToUTF16("element");
1539 expected.max_length = 0;
1540 expected.form_control_type = "select-one";
1542 expected.value = ASCIIToUTF16("CA");
1543 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result1);
1545 FormFieldData result2;
1546 WebFormControlElementToFormField(
1547 element,
1548 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTION_TEXT),
1549 &result2);
1550 expected.value = ASCIIToUTF16("California");
1551 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result2);
1553 FormFieldData result3;
1554 WebFormControlElementToFormField(element, EXTRACT_OPTIONS, &result3);
1555 expected.value.clear();
1556 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result3);
1558 ASSERT_EQ(2U, result3.option_values.size());
1559 ASSERT_EQ(2U, result3.option_contents.size());
1560 EXPECT_EQ(ASCIIToUTF16("CA"), result3.option_values[0]);
1561 EXPECT_EQ(ASCIIToUTF16("California"), result3.option_contents[0]);
1562 EXPECT_EQ(ASCIIToUTF16("TX"), result3.option_values[1]);
1563 EXPECT_EQ(ASCIIToUTF16("Texas"), result3.option_contents[1]);
1566 // We copy extra attributes for the select field.
1567 TEST_F(FormAutofillTest,
1568 WebFormControlElementToFormFieldSelect_ExtraAttributes) {
1569 LoadHTML("<SELECT id='element' autocomplete='off'/>"
1570 " <OPTION value='CA'>California</OPTION>"
1571 " <OPTION value='TX'>Texas</OPTION>"
1572 "</SELECT>");
1574 WebFrame* frame = GetMainFrame();
1575 ASSERT_NE(nullptr, frame);
1577 WebFormControlElement element = GetFormControlElementById("element");
1578 element.setAutofilled(true);
1580 FormFieldData result1;
1581 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result1);
1583 FormFieldData expected;
1584 expected.name = ASCIIToUTF16("element");
1585 expected.max_length = 0;
1586 expected.form_control_type = "select-one";
1587 // We check that the extra attributes have been copied to |result1|.
1588 expected.is_autofilled = true;
1589 expected.autocomplete_attribute = "off";
1590 expected.should_autocomplete = false;
1591 expected.is_focusable = true;
1592 expected.text_direction = base::i18n::LEFT_TO_RIGHT;
1594 expected.value = ASCIIToUTF16("CA");
1595 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result1);
1598 // When faced with <select> field with *many* options, we should trim them to a
1599 // reasonable number.
1600 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldLongSelect) {
1601 std::string html = "<SELECT id='element'/>";
1602 for (size_t i = 0; i < 2 * kMaxListSize; ++i) {
1603 html += base::StringPrintf("<OPTION value='%" PRIuS "'>"
1604 "%" PRIuS "</OPTION>", i, i);
1606 html += "</SELECT>";
1607 LoadHTML(html.c_str());
1609 WebFrame* frame = GetMainFrame();
1610 ASSERT_TRUE(frame);
1612 WebFormControlElement element = GetFormControlElementById("element");
1613 FormFieldData result;
1614 WebFormControlElementToFormField(element, EXTRACT_OPTIONS, &result);
1616 EXPECT_TRUE(result.option_values.empty());
1617 EXPECT_TRUE(result.option_contents.empty());
1620 // We should be able to extract a <textarea> field.
1621 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldTextArea) {
1622 LoadHTML("<TEXTAREA id='element'>"
1623 "This element's value&#10;"
1624 "spans multiple lines."
1625 "</TEXTAREA>");
1627 WebFrame* frame = GetMainFrame();
1628 ASSERT_NE(nullptr, frame);
1630 WebFormControlElement element = GetFormControlElementById("element");
1631 FormFieldData result_sans_value;
1632 WebFormControlElementToFormField(element, EXTRACT_NONE, &result_sans_value);
1634 FormFieldData expected;
1635 expected.name = ASCIIToUTF16("element");
1636 expected.max_length = 0;
1637 expected.form_control_type = "textarea";
1638 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result_sans_value);
1640 FormFieldData result_with_value;
1641 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result_with_value);
1642 expected.value = ASCIIToUTF16("This element's value\n"
1643 "spans multiple lines.");
1644 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result_with_value);
1647 // We should be able to extract an <input type="month"> field.
1648 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMonthInput) {
1649 LoadHTML("<INPUT type='month' id='element' value='2011-12'>");
1651 WebFrame* frame = GetMainFrame();
1652 ASSERT_NE(nullptr, frame);
1654 WebFormControlElement element = GetFormControlElementById("element");
1655 FormFieldData result_sans_value;
1656 WebFormControlElementToFormField(element, EXTRACT_NONE, &result_sans_value);
1658 FormFieldData expected;
1659 expected.name = ASCIIToUTF16("element");
1660 expected.max_length = 0;
1661 expected.form_control_type = "month";
1662 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result_sans_value);
1664 FormFieldData result_with_value;
1665 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result_with_value);
1666 expected.value = ASCIIToUTF16("2011-12");
1667 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result_with_value);
1670 // We should not extract the value for non-text and non-select fields.
1671 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldInvalidType) {
1672 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
1673 " <INPUT type='hidden' id='hidden' value='apple'/>"
1674 " <INPUT type='submit' id='submit' value='Send'/>"
1675 "</FORM>");
1677 WebFrame* frame = GetMainFrame();
1678 ASSERT_NE(nullptr, frame);
1680 WebFormControlElement element = GetFormControlElementById("hidden");
1681 FormFieldData result;
1682 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1684 FormFieldData expected;
1685 expected.max_length = 0;
1687 expected.name = ASCIIToUTF16("hidden");
1688 expected.form_control_type = "hidden";
1689 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1691 element = GetFormControlElementById("submit");
1692 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1693 expected.name = ASCIIToUTF16("submit");
1694 expected.form_control_type = "submit";
1695 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1698 // We should be able to extract password fields.
1699 TEST_F(FormAutofillTest, WebFormControlElementToPasswordFormField) {
1700 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
1701 " <INPUT type='password' id='password' value='secret'/>"
1702 "</FORM>");
1704 WebFrame* frame = GetMainFrame();
1705 ASSERT_NE(nullptr, frame);
1707 WebFormControlElement element = GetFormControlElementById("password");
1708 FormFieldData result;
1709 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1711 FormFieldData expected;
1712 expected.max_length = WebInputElement::defaultMaxLength();
1713 expected.name = ASCIIToUTF16("password");
1714 expected.form_control_type = "password";
1715 expected.value = ASCIIToUTF16("secret");
1716 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1719 // We should be able to extract the autocompletetype attribute.
1720 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompletetype) {
1721 std::string html =
1722 "<INPUT type='text' id='absent'/>"
1723 "<INPUT type='text' id='empty' autocomplete=''/>"
1724 "<INPUT type='text' id='off' autocomplete='off'/>"
1725 "<INPUT type='text' id='regular' autocomplete='email'/>"
1726 "<INPUT type='text' id='multi-valued' "
1727 " autocomplete='billing email'/>"
1728 "<INPUT type='text' id='experimental' x-autocompletetype='email'/>"
1729 "<INPUT type='month' id='month' autocomplete='cc-exp'/>"
1730 "<SELECT id='select' autocomplete='state'/>"
1731 " <OPTION value='CA'>California</OPTION>"
1732 " <OPTION value='TX'>Texas</OPTION>"
1733 "</SELECT>"
1734 "<TEXTAREA id='textarea' autocomplete='street-address'>"
1735 " Some multi-"
1736 " lined value"
1737 "</TEXTAREA>";
1738 html +=
1739 "<INPUT type='text' id='malicious' autocomplete='" +
1740 std::string(10000, 'x') + "'/>";
1741 LoadHTML(html.c_str());
1743 WebFrame* frame = GetMainFrame();
1744 ASSERT_NE(nullptr, frame);
1746 struct TestCase {
1747 const std::string element_id;
1748 const std::string form_control_type;
1749 const std::string autocomplete_attribute;
1751 TestCase test_cases[] = {
1752 // An absent attribute is equivalent to an empty one.
1753 { "absent", "text", "" },
1754 // Make sure there are no issues parsing an empty attribute.
1755 { "empty", "text", "" },
1756 // Make sure there are no issues parsing an attribute value that isn't a
1757 // type hint.
1758 { "off", "text", "off" },
1759 // Common case: exactly one type specified.
1760 { "regular", "text", "email" },
1761 // Verify that we correctly extract multiple tokens as well.
1762 { "multi-valued", "text", "billing email" },
1763 // Verify that <input type="month"> fields are supported.
1764 { "month", "month", "cc-exp" },
1765 // We previously extracted this data from the experimental
1766 // 'x-autocompletetype' attribute. Now that the field type hints are part
1767 // of the spec under the autocomplete attribute, we no longer support the
1768 // experimental version.
1769 { "experimental", "text", "" },
1770 // <select> elements should behave no differently from text fields here.
1771 { "select", "select-one", "state" },
1772 // <textarea> elements should also behave no differently from text fields.
1773 { "textarea", "textarea", "street-address" },
1774 // Very long attribute values should be replaced by a default string, to
1775 // prevent malicious websites from DOSing the browser process.
1776 { "malicious", "text", "x-max-data-length-exceeded" },
1779 WebDocument document = frame->document();
1780 for (size_t i = 0; i < arraysize(test_cases); ++i) {
1781 WebFormControlElement element =
1782 GetFormControlElementById(ASCIIToUTF16(test_cases[i].element_id));
1783 FormFieldData result;
1784 WebFormControlElementToFormField(element, EXTRACT_NONE, &result);
1786 FormFieldData expected;
1787 expected.name = ASCIIToUTF16(test_cases[i].element_id);
1788 expected.form_control_type = test_cases[i].form_control_type;
1789 expected.autocomplete_attribute = test_cases[i].autocomplete_attribute;
1790 if (test_cases[i].form_control_type == "text")
1791 expected.max_length = WebInputElement::defaultMaxLength();
1792 else
1793 expected.max_length = 0;
1795 SCOPED_TRACE(test_cases[i].element_id);
1796 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
1800 TEST_F(FormAutofillTest, DetectTextDirectionFromDirectStyle) {
1801 LoadHTML("<STYLE>input{direction:rtl}</STYLE>"
1802 "<FORM>"
1803 " <INPUT type='text' id='element'>"
1804 "</FORM>");
1806 WebFrame* frame = GetMainFrame();
1807 ASSERT_NE(nullptr, frame);
1809 WebFormControlElement element = GetFormControlElementById("element");
1811 FormFieldData result;
1812 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1813 EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
1816 TEST_F(FormAutofillTest, DetectTextDirectionFromDirectDIRAttribute) {
1817 LoadHTML("<FORM>"
1818 " <INPUT dir='rtl' type='text' id='element'/>"
1819 "</FORM>");
1821 WebFrame* frame = GetMainFrame();
1822 ASSERT_NE(nullptr, frame);
1824 WebFormControlElement element = GetFormControlElementById("element");
1826 FormFieldData result;
1827 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1828 EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
1831 TEST_F(FormAutofillTest, DetectTextDirectionFromParentStyle) {
1832 LoadHTML("<STYLE>form{direction:rtl}</STYLE>"
1833 "<FORM>"
1834 " <INPUT type='text' id='element'/>"
1835 "</FORM>");
1837 WebFrame* frame = GetMainFrame();
1838 ASSERT_NE(nullptr, frame);
1840 WebFormControlElement element = GetFormControlElementById("element");
1842 FormFieldData result;
1843 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1844 EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
1847 TEST_F(FormAutofillTest, DetectTextDirectionFromParentDIRAttribute) {
1848 LoadHTML("<FORM dir='rtl'>"
1849 " <INPUT type='text' id='element'/>"
1850 "</FORM>");
1852 WebFrame* frame = GetMainFrame();
1853 ASSERT_NE(nullptr, frame);
1855 WebFormControlElement element = GetFormControlElementById("element");
1857 FormFieldData result;
1858 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1859 EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
1862 TEST_F(FormAutofillTest, DetectTextDirectionWhenStyleAndDIRAttributMixed) {
1863 LoadHTML("<STYLE>input{direction:ltr}</STYLE>"
1864 "<FORM dir='rtl'>"
1865 " <INPUT type='text' id='element'/>"
1866 "</FORM>");
1868 WebFrame* frame = GetMainFrame();
1869 ASSERT_NE(nullptr, frame);
1871 WebFormControlElement element = GetFormControlElementById("element");
1873 FormFieldData result;
1874 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1875 EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction);
1878 TEST_F(FormAutofillTest,
1879 DetectTextDirectionWhenParentHasBothDIRAttributeAndStyle) {
1880 LoadHTML("<STYLE>form{direction:ltr}</STYLE>"
1881 "<FORM dir='rtl'>"
1882 " <INPUT type='text' id='element'/>"
1883 "</FORM>");
1885 WebFrame* frame = GetMainFrame();
1886 ASSERT_NE(nullptr, frame);
1888 WebFormControlElement element = GetFormControlElementById("element");
1890 FormFieldData result;
1891 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1892 EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction);
1895 TEST_F(FormAutofillTest, DetectTextDirectionWhenAncestorHasInlineStyle) {
1896 LoadHTML("<FORM style='direction:ltr'>"
1897 " <SPAN dir='rtl'>"
1898 " <INPUT type='text' id='element'/>"
1899 " </SPAN>"
1900 "</FORM>");
1902 WebFrame* frame = GetMainFrame();
1903 ASSERT_NE(nullptr, frame);
1905 WebFormControlElement element = GetFormControlElementById("element");
1907 FormFieldData result;
1908 WebFormControlElementToFormField(element, EXTRACT_VALUE, &result);
1909 EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
1912 TEST_F(FormAutofillTest, WebFormElementToFormData) {
1913 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
1914 " <LABEL for='firstname'>First name:</LABEL>"
1915 " <INPUT type='text' id='firstname' value='John'/>"
1916 " <LABEL for='lastname'>Last name:</LABEL>"
1917 " <INPUT type='text' id='lastname' value='Smith'/>"
1918 " <LABEL for='street-address'>Address:</LABEL>"
1919 " <TEXTAREA id='street-address'>"
1920 "123 Fantasy Ln.&#10;"
1921 "Apt. 42"
1922 "</TEXTAREA>"
1923 " <LABEL for='state'>State:</LABEL>"
1924 " <SELECT id='state'/>"
1925 " <OPTION value='CA'>California</OPTION>"
1926 " <OPTION value='TX'>Texas</OPTION>"
1927 " </SELECT>"
1928 " <LABEL for='password'>Password:</LABEL>"
1929 " <INPUT type='password' id='password' value='secret'/>"
1930 " <LABEL for='month'>Card expiration:</LABEL>"
1931 " <INPUT type='month' id='month' value='2011-12'/>"
1932 " <INPUT type='submit' name='reply-send' value='Send'/>"
1933 // The below inputs should be ignored
1934 " <LABEL for='notvisible'>Hidden:</LABEL>"
1935 " <INPUT type='hidden' id='notvisible' value='apple'/>"
1936 "</FORM>");
1938 WebFrame* frame = GetMainFrame();
1939 ASSERT_NE(nullptr, frame);
1941 WebVector<WebFormElement> forms;
1942 frame->document().forms(forms);
1943 ASSERT_EQ(1U, forms.size());
1945 WebInputElement input_element = GetInputElementById("firstname");
1947 FormData form;
1948 FormFieldData field;
1949 EXPECT_TRUE(WebFormElementToFormData(forms[0],
1950 input_element,
1951 EXTRACT_VALUE,
1952 &form,
1953 &field));
1954 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
1955 EXPECT_EQ(GURL(frame->document().url()), form.origin);
1956 EXPECT_FALSE(form.origin.is_empty());
1957 EXPECT_EQ(GURL("http://cnn.com"), form.action);
1959 const std::vector<FormFieldData>& fields = form.fields;
1960 ASSERT_EQ(6U, fields.size());
1962 FormFieldData expected;
1963 expected.name = ASCIIToUTF16("firstname");
1964 expected.value = ASCIIToUTF16("John");
1965 expected.label = ASCIIToUTF16("First name:");
1966 expected.form_control_type = "text";
1967 expected.max_length = WebInputElement::defaultMaxLength();
1968 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
1970 expected.name = ASCIIToUTF16("lastname");
1971 expected.value = ASCIIToUTF16("Smith");
1972 expected.label = ASCIIToUTF16("Last name:");
1973 expected.form_control_type = "text";
1974 expected.max_length = WebInputElement::defaultMaxLength();
1975 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
1977 expected.name = ASCIIToUTF16("street-address");
1978 expected.value = ASCIIToUTF16("123 Fantasy Ln.\nApt. 42");
1979 expected.label = ASCIIToUTF16("Address:");
1980 expected.form_control_type = "textarea";
1981 expected.max_length = 0;
1982 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
1984 expected.name = ASCIIToUTF16("state");
1985 expected.value = ASCIIToUTF16("CA");
1986 expected.label = ASCIIToUTF16("State:");
1987 expected.form_control_type = "select-one";
1988 expected.max_length = 0;
1989 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
1991 expected.name = ASCIIToUTF16("password");
1992 expected.value = ASCIIToUTF16("secret");
1993 expected.label = ASCIIToUTF16("Password:");
1994 expected.form_control_type = "password";
1995 expected.max_length = WebInputElement::defaultMaxLength();
1996 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[4]);
1998 expected.name = ASCIIToUTF16("month");
1999 expected.value = ASCIIToUTF16("2011-12");
2000 expected.label = ASCIIToUTF16("Card expiration:");
2001 expected.form_control_type = "month";
2002 expected.max_length = 0;
2003 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[5]);
2006 // We should not be able to serialize a form with too many fillable fields.
2007 TEST_F(FormAutofillTest, WebFormElementToFormDataTooManyFields) {
2008 std::string html =
2009 "<FORM name='TestForm' action='http://cnn.com' method='post'>";
2010 for (size_t i = 0; i < (kMaxParseableFields + 1); ++i) {
2011 html += "<INPUT type='text'/>";
2013 html += "</FORM>";
2014 LoadHTML(html.c_str());
2016 WebFrame* frame = GetMainFrame();
2017 ASSERT_NE(nullptr, frame);
2019 WebVector<WebFormElement> forms;
2020 frame->document().forms(forms);
2021 ASSERT_EQ(1U, forms.size());
2023 WebInputElement input_element = GetInputElementById("firstname");
2025 FormData form;
2026 FormFieldData field;
2027 EXPECT_FALSE(WebFormElementToFormData(forms[0],
2028 input_element,
2029 EXTRACT_VALUE,
2030 &form,
2031 &field));
2034 TEST_F(FormAutofillTest, ExtractForms) {
2035 ExpectJohnSmithLabels(
2036 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2037 " First name: <INPUT type='text' id='firstname' value='John'/>"
2038 " Last name: <INPUT type='text' id='lastname' value='Smith'/>"
2039 " Email: <INPUT type='text' id='email' value='john@example.com'/>"
2040 " <INPUT type='submit' name='reply-send' value='Send'/>"
2041 "</FORM>");
2044 TEST_F(FormAutofillTest, ExtractMultipleForms) {
2045 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
2046 " <INPUT type='text' id='firstname' value='John'/>"
2047 " <INPUT type='text' id='lastname' value='Smith'/>"
2048 " <INPUT type='text' id='email' value='john@example.com'/>"
2049 " <INPUT type='submit' name='reply-send' value='Send'/>"
2050 "</FORM>"
2051 "<FORM name='TestForm2' action='http://zoo.com' method='post'>"
2052 " <INPUT type='text' id='firstname' value='Jack'/>"
2053 " <INPUT type='text' id='lastname' value='Adams'/>"
2054 " <INPUT type='text' id='email' value='jack@example.com'/>"
2055 " <INPUT type='submit' name='reply-send' value='Send'/>"
2056 "</FORM>");
2058 WebFrame* web_frame = GetMainFrame();
2059 ASSERT_NE(nullptr, web_frame);
2061 FormCache form_cache(*web_frame);
2062 std::vector<FormData> forms = form_cache.ExtractNewForms();
2063 ASSERT_EQ(2U, forms.size());
2065 // First form.
2066 const FormData& form = forms[0];
2067 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
2068 EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
2069 EXPECT_FALSE(form.origin.is_empty());
2070 EXPECT_EQ(GURL("http://cnn.com"), form.action);
2072 const std::vector<FormFieldData>& fields = form.fields;
2073 ASSERT_EQ(3U, fields.size());
2075 FormFieldData expected;
2076 expected.form_control_type = "text";
2077 expected.max_length = WebInputElement::defaultMaxLength();
2079 expected.name = ASCIIToUTF16("firstname");
2080 expected.value = ASCIIToUTF16("John");
2081 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
2083 expected.name = ASCIIToUTF16("lastname");
2084 expected.value = ASCIIToUTF16("Smith");
2085 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
2087 expected.name = ASCIIToUTF16("email");
2088 expected.value = ASCIIToUTF16("john@example.com");
2089 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
2091 // Second form.
2092 const FormData& form2 = forms[1];
2093 EXPECT_EQ(ASCIIToUTF16("TestForm2"), form2.name);
2094 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
2095 EXPECT_FALSE(form.origin.is_empty());
2096 EXPECT_EQ(GURL("http://zoo.com"), form2.action);
2098 const std::vector<FormFieldData>& fields2 = form2.fields;
2099 ASSERT_EQ(3U, fields2.size());
2101 expected.name = ASCIIToUTF16("firstname");
2102 expected.value = ASCIIToUTF16("Jack");
2103 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
2105 expected.name = ASCIIToUTF16("lastname");
2106 expected.value = ASCIIToUTF16("Adams");
2107 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
2109 expected.name = ASCIIToUTF16("email");
2110 expected.value = ASCIIToUTF16("jack@example.com");
2111 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
2114 TEST_F(FormAutofillTest, OnlyExtractNewForms) {
2115 LoadHTML(
2116 "<FORM id='testform' action='http://cnn.com' method='post'>"
2117 " <INPUT type='text' id='firstname' value='John'/>"
2118 " <INPUT type='text' id='lastname' value='Smith'/>"
2119 " <INPUT type='text' id='email' value='john@example.com'/>"
2120 " <INPUT type='submit' name='reply-send' value='Send'/>"
2121 "</FORM>");
2123 WebFrame* web_frame = GetMainFrame();
2124 ASSERT_NE(nullptr, web_frame);
2126 FormCache form_cache(*web_frame);
2127 std::vector<FormData> forms = form_cache.ExtractNewForms();
2128 ASSERT_EQ(1U, forms.size());
2130 // Second call should give nothing as there are no new forms.
2131 forms = form_cache.ExtractNewForms();
2132 ASSERT_TRUE(forms.empty());
2134 // Append to the current form will re-extract.
2135 ExecuteJavaScriptForTests(
2136 "var newInput = document.createElement('input');"
2137 "newInput.setAttribute('type', 'text');"
2138 "newInput.setAttribute('id', 'telephone');"
2139 "newInput.value = '12345';"
2140 "document.getElementById('testform').appendChild(newInput);");
2141 msg_loop_.RunUntilIdle();
2143 forms = form_cache.ExtractNewForms();
2144 ASSERT_EQ(1U, forms.size());
2146 const std::vector<FormFieldData>& fields = forms[0].fields;
2147 ASSERT_EQ(4U, fields.size());
2149 FormFieldData expected;
2150 expected.form_control_type = "text";
2151 expected.max_length = WebInputElement::defaultMaxLength();
2153 expected.name = ASCIIToUTF16("firstname");
2154 expected.value = ASCIIToUTF16("John");
2155 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
2157 expected.name = ASCIIToUTF16("lastname");
2158 expected.value = ASCIIToUTF16("Smith");
2159 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
2161 expected.name = ASCIIToUTF16("email");
2162 expected.value = ASCIIToUTF16("john@example.com");
2163 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
2165 expected.name = ASCIIToUTF16("telephone");
2166 expected.value = ASCIIToUTF16("12345");
2167 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
2169 forms.clear();
2171 // Completely new form will also be extracted.
2172 ExecuteJavaScriptForTests(
2173 "var newForm=document.createElement('form');"
2174 "newForm.id='new_testform';"
2175 "newForm.action='http://google.com';"
2176 "newForm.method='post';"
2177 "var newFirstname=document.createElement('input');"
2178 "newFirstname.setAttribute('type', 'text');"
2179 "newFirstname.setAttribute('id', 'second_firstname');"
2180 "newFirstname.value = 'Bob';"
2181 "var newLastname=document.createElement('input');"
2182 "newLastname.setAttribute('type', 'text');"
2183 "newLastname.setAttribute('id', 'second_lastname');"
2184 "newLastname.value = 'Hope';"
2185 "var newEmail=document.createElement('input');"
2186 "newEmail.setAttribute('type', 'text');"
2187 "newEmail.setAttribute('id', 'second_email');"
2188 "newEmail.value = 'bobhope@example.com';"
2189 "newForm.appendChild(newFirstname);"
2190 "newForm.appendChild(newLastname);"
2191 "newForm.appendChild(newEmail);"
2192 "document.body.appendChild(newForm);");
2193 msg_loop_.RunUntilIdle();
2195 web_frame = GetMainFrame();
2196 forms = form_cache.ExtractNewForms();
2197 ASSERT_EQ(1U, forms.size());
2199 const std::vector<FormFieldData>& fields2 = forms[0].fields;
2200 ASSERT_EQ(3U, fields2.size());
2202 expected.name = ASCIIToUTF16("second_firstname");
2203 expected.value = ASCIIToUTF16("Bob");
2204 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
2206 expected.name = ASCIIToUTF16("second_lastname");
2207 expected.value = ASCIIToUTF16("Hope");
2208 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
2210 expected.name = ASCIIToUTF16("second_email");
2211 expected.value = ASCIIToUTF16("bobhope@example.com");
2212 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
2215 // We should not extract a form if it has too few fillable fields.
2216 TEST_F(FormAutofillTest, ExtractFormsTooFewFields) {
2217 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
2218 " <INPUT type='text' id='firstname' value='John'/>"
2219 " <INPUT type='text' id='lastname' value='Smith'/>"
2220 " <INPUT type='submit' name='reply-send' value='Send'/>"
2221 "</FORM>");
2223 WebFrame* web_frame = GetMainFrame();
2224 ASSERT_NE(nullptr, web_frame);
2226 FormCache form_cache(*web_frame);
2227 std::vector<FormData> forms = form_cache.ExtractNewForms();
2228 ASSERT_TRUE(forms.empty());
2231 // We should not report additional forms for empty forms.
2232 TEST_F(FormAutofillTest, ExtractFormsSkippedForms) {
2233 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
2234 " <INPUT type='text' id='firstname' value='John'/>"
2235 " <INPUT type='text' id='lastname' value='Smith'/>"
2236 "</FORM>");
2238 WebFrame* web_frame = GetMainFrame();
2239 ASSERT_NE(nullptr, web_frame);
2241 FormCache form_cache(*web_frame);
2242 std::vector<FormData> forms = form_cache.ExtractNewForms();
2243 ASSERT_TRUE(forms.empty());
2246 // We should not report additional forms for empty forms.
2247 TEST_F(FormAutofillTest, ExtractFormsNoFields) {
2248 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
2249 "</FORM>");
2251 WebFrame* web_frame = GetMainFrame();
2252 ASSERT_NE(nullptr, web_frame);
2254 FormCache form_cache(*web_frame);
2255 std::vector<FormData> forms = form_cache.ExtractNewForms();
2256 ASSERT_TRUE(forms.empty());
2259 // We should not extract a form if it has too few fillable fields.
2260 // Make sure radio and checkbox fields don't count.
2261 TEST_F(FormAutofillTest, ExtractFormsTooFewFieldsSkipsCheckable) {
2262 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
2263 " <INPUT type='text' id='firstname' value='John'/>"
2264 " <INPUT type='text' id='lastname' value='Smith'/>"
2265 " <INPUT type='radio' id='a_radio' value='0'/>"
2266 " <INPUT type='checkbox' id='a_check' value='1'/>"
2267 " <INPUT type='submit' name='reply-send' value='Send'/>"
2268 "</FORM>");
2270 WebFrame* web_frame = GetMainFrame();
2271 ASSERT_NE(nullptr, web_frame);
2273 FormCache form_cache(*web_frame);
2274 std::vector<FormData> forms = form_cache.ExtractNewForms();
2275 ASSERT_TRUE(forms.empty());
2278 TEST_F(FormAutofillTest, WebFormElementToFormDataAutocomplete) {
2280 // Form is still Autofill-able despite autocomplete=off.
2281 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'"
2282 " autocomplete=off>"
2283 " <INPUT type='text' id='firstname' value='John'/>"
2284 " <INPUT type='text' id='lastname' value='Smith'/>"
2285 " <INPUT type='text' id='email' value='john@example.com'/>"
2286 " <INPUT type='submit' name='reply-send' value='Send'/>"
2287 "</FORM>");
2289 WebFrame* web_frame = GetMainFrame();
2290 ASSERT_NE(nullptr, web_frame);
2292 WebVector<WebFormElement> web_forms;
2293 web_frame->document().forms(web_forms);
2294 ASSERT_EQ(1U, web_forms.size());
2295 WebFormElement web_form = web_forms[0];
2297 FormData form;
2298 EXPECT_TRUE(WebFormElementToFormData(web_form, WebFormControlElement(),
2299 EXTRACT_NONE, &form, nullptr));
2303 TEST_F(FormAutofillTest, FindFormForInputElement) {
2304 TestFindFormForInputElement(
2305 "<FORM name='TestForm' action='http://buh.com' method='post'>"
2306 " <INPUT type='text' id='firstname' value='John'/>"
2307 " <INPUT type='text' id='lastname' value='Smith'/>"
2308 " <INPUT type='text' id='email' value='john@example.com'"
2309 "autocomplete='off' />"
2310 " <INPUT type='text' id='phone' value='1.800.555.1234'/>"
2311 " <INPUT type='submit' name='reply-send' value='Send'/>"
2312 "</FORM>",
2313 false);
2316 TEST_F(FormAutofillTest, FindFormForInputElementForUnownedForm) {
2317 TestFindFormForInputElement(
2318 "<HEAD><TITLE>delivery recipient</TITLE></HEAD>"
2319 "<INPUT type='text' id='firstname' value='John'/>"
2320 "<INPUT type='text' id='lastname' value='Smith'/>"
2321 "<INPUT type='text' id='email' value='john@example.com'"
2322 "autocomplete='off' />"
2323 "<INPUT type='text' id='phone' value='1.800.555.1234'/>"
2324 "<INPUT type='submit' name='reply-send' value='Send'/>",
2325 true);
2328 TEST_F(FormAutofillTest, FindFormForTextAreaElement) {
2329 TestFindFormForTextAreaElement(
2330 "<FORM name='TestForm' action='http://buh.com' method='post'>"
2331 " <INPUT type='text' id='firstname' value='John'/>"
2332 " <INPUT type='text' id='lastname' value='Smith'/>"
2333 " <INPUT type='text' id='email' value='john@example.com'"
2334 "autocomplete='off' />"
2335 " <TEXTAREA id='street-address'>"
2336 "123 Fantasy Ln.&#10;"
2337 "Apt. 42"
2338 "</TEXTAREA>"
2339 " <INPUT type='submit' name='reply-send' value='Send'/>"
2340 "</FORM>",
2341 false);
2344 TEST_F(FormAutofillTest, FindFormForTextAreaElementForUnownedForm) {
2345 TestFindFormForTextAreaElement(
2346 "<HEAD><TITLE>delivery address</TITLE></HEAD>"
2347 "<INPUT type='text' id='firstname' value='John'/>"
2348 "<INPUT type='text' id='lastname' value='Smith'/>"
2349 "<INPUT type='text' id='email' value='john@example.com'"
2350 "autocomplete='off' />"
2351 "<TEXTAREA id='street-address'>"
2352 "123 Fantasy Ln.&#10;"
2353 "Apt. 42"
2354 "</TEXTAREA>"
2355 "<INPUT type='submit' name='reply-send' value='Send'/>",
2356 true);
2359 // Test regular FillForm function.
2360 TEST_F(FormAutofillTest, FillForm) {
2361 TestFillForm(kFormHtml, false);
2364 TEST_F(FormAutofillTest, FillFormForUnownedForm) {
2365 TestFillForm(kUnownedFormHtml, true);
2368 TEST_F(FormAutofillTest, FillFormIncludingNonFocusableElements) {
2369 static const AutofillFieldCase field_cases[] = {
2370 // fields: form_control_type, name, initial_value, autocomplete_attribute,
2371 // should_be_autofilled, autofill_value, expected_value
2373 // Regular empty fields (firstname & lastname) should be autofilled.
2374 {"text",
2375 "firstname",
2378 true,
2379 "filled firstname",
2380 "filled firstname"},
2381 {"text", "lastname", "", "", true, "filled lastname", "filled lastname"},
2382 // hidden fields should not be extracted to form_data.
2383 // Non empty fields should be overriden.
2384 {"text",
2385 "notempty",
2386 "Hi",
2388 true,
2389 "filled notempty",
2390 "filled notempty"},
2391 {"text",
2392 "noautocomplete",
2394 "off",
2395 true,
2396 "filled noautocomplete",
2397 "filled noautocomplete"},
2398 // Disabled fields should not be autofilled.
2399 {"text", "notenabled", "", "", false, "filled notenabled", ""},
2400 // Readonly fields should not be autofilled.
2401 {"text", "readonly", "", "", false, "filled readonly", ""},
2402 // Fields with "visibility: hidden" should also be autofilled.
2403 {"text",
2404 "invisible",
2407 true,
2408 "filled invisible",
2409 "filled invisible"},
2410 // Fields with "display:none" should also be autofilled.
2411 {"text",
2412 "displaynone",
2415 true,
2416 "filled displaynone",
2417 "filled displaynone"},
2418 // Regular <input type="month"> should be autofilled.
2419 {"month", "month", "", "", true, "2017-11", "2017-11"},
2420 // Non-empty <input type="month"> should be overridden.
2421 {"month", "month-nonempty", "2011-12", "", true, "2017-11", "2017-11"},
2422 // Regular select fields should be autofilled.
2423 {"select-one", "select", "", "", true, "TX", "TX"},
2424 // Select fields should be autofilled even if they already have a
2425 // non-empty value.
2426 {"select-one", "select-nonempty", "CA", "", true, "TX", "TX"},
2427 // Select fields should not be autofilled if no new value is passed from
2428 // autofill profile. The existing value should not be overriden.
2429 {"select-one", "select-unchanged", "CA", "", false, "CA", "CA"},
2430 // Regular textarea elements should be autofilled.
2431 {"textarea",
2432 "textarea",
2435 true,
2436 "some multi-\nline value",
2437 "some multi-\nline value"},
2438 // Nonempty textarea elements should be overridden.
2439 {"textarea",
2440 "textarea-nonempty",
2441 "Go\naway!",
2443 true,
2444 "some multi-\nline value",
2445 "some multi-\nline value"},
2447 TestFormFillFunctions(kFormHtml, false, field_cases, arraysize(field_cases),
2448 &FillFormIncludingNonFocusableElementsWrapper,
2449 &GetValueWrapper);
2452 TEST_F(FormAutofillTest, PreviewForm) {
2453 TestPreviewForm(kFormHtml, false);
2456 TEST_F(FormAutofillTest, PreviewFormForUnownedForm) {
2457 TestPreviewForm(kUnownedFormHtml, true);
2460 TEST_F(FormAutofillTest, Labels) {
2461 ExpectJohnSmithLabels(
2462 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2463 " <LABEL for='firstname'> First name: </LABEL>"
2464 " <INPUT type='text' id='firstname' value='John'/>"
2465 " <LABEL for='lastname'> Last name: </LABEL>"
2466 " <INPUT type='text' id='lastname' value='Smith'/>"
2467 " <LABEL for='email'> Email: </LABEL>"
2468 " <INPUT type='text' id='email' value='john@example.com'/>"
2469 " <INPUT type='submit' name='reply-send' value='Send'/>"
2470 "</FORM>");
2473 TEST_F(FormAutofillTest, LabelsWithSpans) {
2474 ExpectJohnSmithLabels(
2475 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2476 " <LABEL for='firstname'><span>First name: </span></LABEL>"
2477 " <INPUT type='text' id='firstname' value='John'/>"
2478 " <LABEL for='lastname'><span>Last name: </span></LABEL>"
2479 " <INPUT type='text' id='lastname' value='Smith'/>"
2480 " <LABEL for='email'><span>Email: </span></LABEL>"
2481 " <INPUT type='text' id='email' value='john@example.com'/>"
2482 " <INPUT type='submit' name='reply-send' value='Send'/>"
2483 "</FORM>");
2486 // This test is different from FormAutofillTest.Labels in that the label
2487 // elements for= attribute is set to the name of the form control element it is
2488 // a label for instead of the id of the form control element. This is invalid
2489 // because the for= attribute must be set to the id of the form control element;
2490 // however, current label parsing code will extract the text from the previous
2491 // label element and apply it to the following input field.
2492 TEST_F(FormAutofillTest, InvalidLabels) {
2493 ExpectJohnSmithLabels(
2494 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2495 " <LABEL for='firstname'> First name: </LABEL>"
2496 " <INPUT type='text' name='firstname' value='John'/>"
2497 " <LABEL for='lastname'> Last name: </LABEL>"
2498 " <INPUT type='text' name='lastname' value='Smith'/>"
2499 " <LABEL for='email'> Email: </LABEL>"
2500 " <INPUT type='text' name='email' value='john@example.com'/>"
2501 " <INPUT type='submit' name='reply-send' value='Send'/>"
2502 "</FORM>");
2505 // This test has three form control elements, only one of which has a label
2506 // element associated with it.
2507 TEST_F(FormAutofillTest, OneLabelElement) {
2508 ExpectJohnSmithLabels(
2509 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2510 " First name:"
2511 " <INPUT type='text' id='firstname' value='John'/>"
2512 " <LABEL for='lastname'>Last name: </LABEL>"
2513 " <INPUT type='text' id='lastname' value='Smith'/>"
2514 " Email:"
2515 " <INPUT type='text' id='email' value='john@example.com'/>"
2516 " <INPUT type='submit' name='reply-send' value='Send'/>"
2517 "</FORM>");
2520 TEST_F(FormAutofillTest, LabelsInferredFromText) {
2521 ExpectJohnSmithLabels(
2522 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2523 " First name:"
2524 " <INPUT type='text' id='firstname' value='John'/>"
2525 " Last name:"
2526 " <INPUT type='text' id='lastname' value='Smith'/>"
2527 " Email:"
2528 " <INPUT type='text' id='email' value='john@example.com'/>"
2529 " <INPUT type='submit' name='reply-send' value='Send'/>"
2530 "</FORM>");
2533 TEST_F(FormAutofillTest, LabelsInferredFromParagraph) {
2534 ExpectJohnSmithLabels(
2535 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2536 " <P>First name:</P><INPUT type='text' "
2537 " id='firstname' value='John'/>"
2538 " <P>Last name:</P>"
2539 " <INPUT type='text' id='lastname' value='Smith'/>"
2540 " <P>Email:</P>"
2541 " <INPUT type='text' id='email' value='john@example.com'/>"
2542 " <INPUT type='submit' name='reply-send' value='Send'/>"
2543 "</FORM>");
2546 TEST_F(FormAutofillTest, LabelsInferredFromBold) {
2547 ExpectJohnSmithLabels(
2548 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2549 " <B>First name:</B><INPUT type='text' "
2550 " id='firstname' value='John'/>"
2551 " <B>Last name:</B>"
2552 " <INPUT type='text' id='lastname' value='Smith'/>"
2553 " <B>Email:</B>"
2554 " <INPUT type='text' id='email' value='john@example.com'/>"
2555 " <INPUT type='submit' name='reply-send' value='Send'/>"
2556 "</FORM>");
2559 TEST_F(FormAutofillTest, LabelsInferredPriorToImgOrBr) {
2560 ExpectJohnSmithLabels(
2561 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2562 " First name:<IMG/><INPUT type='text' "
2563 " id='firstname' value='John'/>"
2564 " Last name:<IMG/>"
2565 " <INPUT type='text' id='lastname' value='Smith'/>"
2566 " Email:<BR/>"
2567 " <INPUT type='text' id='email' value='john@example.com'/>"
2568 " <INPUT type='submit' name='reply-send' value='Send'/>"
2569 "</FORM>");
2572 TEST_F(FormAutofillTest, LabelsInferredFromTableCell) {
2573 ExpectJohnSmithLabels(
2574 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2575 "<TABLE>"
2576 " <TR>"
2577 " <TD>First name:</TD>"
2578 " <TD><INPUT type='text' id='firstname' value='John'/></TD>"
2579 " </TR>"
2580 " <TR>"
2581 " <TD>Last name:</TD>"
2582 " <TD><INPUT type='text' id='lastname' value='Smith'/></TD>"
2583 " </TR>"
2584 " <TR>"
2585 " <TD>Email:</TD>"
2586 " <TD><INPUT type='text' id='email'"
2587 " value='john@example.com'/></TD>"
2588 " </TR>"
2589 " <TR>"
2590 " <TD></TD>"
2591 " <TD>"
2592 " <INPUT type='submit' name='reply-send' value='Send'/>"
2593 " </TD>"
2594 " </TR>"
2595 "</TABLE>"
2596 "</FORM>");
2599 TEST_F(FormAutofillTest, LabelsInferredFromTableCellTH) {
2600 ExpectJohnSmithLabels(
2601 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2602 "<TABLE>"
2603 " <TR>"
2604 " <TH>First name:</TH>"
2605 " <TD><INPUT type='text' id='firstname' value='John'/></TD>"
2606 " </TR>"
2607 " <TR>"
2608 " <TH>Last name:</TH>"
2609 " <TD><INPUT type='text' id='lastname' value='Smith'/></TD>"
2610 " </TR>"
2611 " <TR>"
2612 " <TH>Email:</TH>"
2613 " <TD><INPUT type='text' id='email'"
2614 " value='john@example.com'/></TD>"
2615 " </TR>"
2616 " <TR>"
2617 " <TD></TD>"
2618 " <TD>"
2619 " <INPUT type='submit' name='reply-send' value='Send'/>"
2620 " </TD>"
2621 " </TR>"
2622 "</TABLE>"
2623 "</FORM>");
2626 TEST_F(FormAutofillTest, LabelsInferredFromTableCellNested) {
2627 std::vector<base::string16> labels, names, values;
2629 labels.push_back(ASCIIToUTF16("First name: Bogus"));
2630 names.push_back(ASCIIToUTF16("firstname"));
2631 values.push_back(ASCIIToUTF16("John"));
2633 labels.push_back(ASCIIToUTF16("Last name:"));
2634 names.push_back(ASCIIToUTF16("lastname"));
2635 values.push_back(ASCIIToUTF16("Smith"));
2637 labels.push_back(ASCIIToUTF16("Email:"));
2638 names.push_back(ASCIIToUTF16("email"));
2639 values.push_back(ASCIIToUTF16("john@example.com"));
2641 ExpectLabels(
2642 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2643 "<TABLE>"
2644 " <TR>"
2645 " <TD>"
2646 " <FONT>"
2647 " First name:"
2648 " </FONT>"
2649 " <FONT>"
2650 " Bogus"
2651 " </FONT>"
2652 " </TD>"
2653 " <TD>"
2654 " <FONT>"
2655 " <INPUT type='text' id='firstname' value='John'/>"
2656 " </FONT>"
2657 " </TD>"
2658 " </TR>"
2659 " <TR>"
2660 " <TD>"
2661 " <FONT>"
2662 " Last name:"
2663 " </FONT>"
2664 " </TD>"
2665 " <TD>"
2666 " <FONT>"
2667 " <INPUT type='text' id='lastname' value='Smith'/>"
2668 " </FONT>"
2669 " </TD>"
2670 " </TR>"
2671 " <TR>"
2672 " <TD>"
2673 " <FONT>"
2674 " Email:"
2675 " </FONT>"
2676 " </TD>"
2677 " <TD>"
2678 " <FONT>"
2679 " <INPUT type='text' id='email' value='john@example.com'/>"
2680 " </FONT>"
2681 " </TD>"
2682 " </TR>"
2683 " <TR>"
2684 " <TD></TD>"
2685 " <TD>"
2686 " <INPUT type='submit' name='reply-send' value='Send'/>"
2687 " </TD>"
2688 " </TR>"
2689 "</TABLE>"
2690 "</FORM>",
2691 labels, names, values);
2694 TEST_F(FormAutofillTest, LabelsInferredFromTableEmptyTDs) {
2695 std::vector<base::string16> labels, names, values;
2697 labels.push_back(ASCIIToUTF16("* First Name"));
2698 names.push_back(ASCIIToUTF16("firstname"));
2699 values.push_back(ASCIIToUTF16("John"));
2701 labels.push_back(ASCIIToUTF16("* Last Name"));
2702 names.push_back(ASCIIToUTF16("lastname"));
2703 values.push_back(ASCIIToUTF16("Smith"));
2705 labels.push_back(ASCIIToUTF16("* Email"));
2706 names.push_back(ASCIIToUTF16("email"));
2707 values.push_back(ASCIIToUTF16("john@example.com"));
2709 ExpectLabels(
2710 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2711 "<TABLE>"
2712 " <TR>"
2713 " <TD>"
2714 " <SPAN>*</SPAN>"
2715 " <B>First Name</B>"
2716 " </TD>"
2717 " <TD></TD>"
2718 " <TD>"
2719 " <INPUT type='text' id='firstname' value='John'/>"
2720 " </TD>"
2721 " </TR>"
2722 " <TR>"
2723 " <TD>"
2724 " <SPAN>*</SPAN>"
2725 " <B>Last Name</B>"
2726 " </TD>"
2727 " <TD></TD>"
2728 " <TD>"
2729 " <INPUT type='text' id='lastname' value='Smith'/>"
2730 " </TD>"
2731 " </TR>"
2732 " <TR>"
2733 " <TD>"
2734 " <SPAN>*</SPAN>"
2735 " <B>Email</B>"
2736 " </TD>"
2737 " <TD></TD>"
2738 " <TD>"
2739 " <INPUT type='text' id='email' value='john@example.com'/>"
2740 " </TD>"
2741 " </TR>"
2742 " <TR>"
2743 " <TD></TD>"
2744 " <TD>"
2745 " <INPUT type='submit' name='reply-send' value='Send'/>"
2746 " </TD>"
2747 " </TR>"
2748 "</TABLE>"
2749 "</FORM>",
2750 labels, names, values);
2753 TEST_F(FormAutofillTest, LabelsInferredFromPreviousTD) {
2754 std::vector<base::string16> labels, names, values;
2756 labels.push_back(ASCIIToUTF16("* First Name"));
2757 names.push_back(ASCIIToUTF16("firstname"));
2758 values.push_back(ASCIIToUTF16("John"));
2760 labels.push_back(ASCIIToUTF16("* Last Name"));
2761 names.push_back(ASCIIToUTF16("lastname"));
2762 values.push_back(ASCIIToUTF16("Smith"));
2764 labels.push_back(ASCIIToUTF16("* Email"));
2765 names.push_back(ASCIIToUTF16("email"));
2766 values.push_back(ASCIIToUTF16("john@example.com"));
2768 ExpectLabels(
2769 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2770 "<TABLE>"
2771 " <TR>"
2772 " <TD>* First Name</TD>"
2773 " <TD>"
2774 " Bogus"
2775 " <INPUT type='hidden'/>"
2776 " <INPUT type='text' id='firstname' value='John'/>"
2777 " </TD>"
2778 " </TR>"
2779 " <TR>"
2780 " <TD>* Last Name</TD>"
2781 " <TD>"
2782 " <INPUT type='text' id='lastname' value='Smith'/>"
2783 " </TD>"
2784 " </TR>"
2785 " <TR>"
2786 " <TD>* Email</TD>"
2787 " <TD>"
2788 " <INPUT type='text' id='email' value='john@example.com'/>"
2789 " </TD>"
2790 " </TR>"
2791 " <TR>"
2792 " <TD></TD>"
2793 " <TD>"
2794 " <INPUT type='submit' name='reply-send' value='Send'/>"
2795 " </TD>"
2796 " </TR>"
2797 "</TABLE>"
2798 "</FORM>",
2799 labels, names, values);
2802 // <script>, <noscript> and <option> tags are excluded when the labels are
2803 // inferred.
2804 // Also <!-- comment --> is excluded.
2805 TEST_F(FormAutofillTest, LabelsInferredFromTableWithSpecialElements) {
2806 std::vector<base::string16> labels, names, values;
2807 std::vector<std::string> control_types;
2809 labels.push_back(ASCIIToUTF16("* First Name"));
2810 names.push_back(ASCIIToUTF16("firstname"));
2811 values.push_back(ASCIIToUTF16("John"));
2812 control_types.push_back("text");
2814 labels.push_back(ASCIIToUTF16("* Middle Name"));
2815 names.push_back(ASCIIToUTF16("middlename"));
2816 values.push_back(ASCIIToUTF16("Joe"));
2817 control_types.push_back("text");
2819 labels.push_back(ASCIIToUTF16("* Last Name"));
2820 names.push_back(ASCIIToUTF16("lastname"));
2821 values.push_back(ASCIIToUTF16("Smith"));
2822 control_types.push_back("text");
2824 labels.push_back(ASCIIToUTF16("* Country"));
2825 names.push_back(ASCIIToUTF16("country"));
2826 values.push_back(ASCIIToUTF16("US"));
2827 control_types.push_back("select-one");
2829 labels.push_back(ASCIIToUTF16("* Email"));
2830 names.push_back(ASCIIToUTF16("email"));
2831 values.push_back(ASCIIToUTF16("john@example.com"));
2832 control_types.push_back("text");
2834 ExpectLabelsAndTypes(
2835 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2836 "<TABLE>"
2837 " <TR>"
2838 " <TD>"
2839 " <SPAN>*</SPAN>"
2840 " <B>First Name</B>"
2841 " </TD>"
2842 " <TD>"
2843 " <SCRIPT> <!-- function test() { alert('ignored as label'); } -->"
2844 " </SCRIPT>"
2845 " <INPUT type='text' id='firstname' value='John'/>"
2846 " </TD>"
2847 " </TR>"
2848 " <TR>"
2849 " <TD>"
2850 " <SPAN>*</SPAN>"
2851 " <B>Middle Name</B>"
2852 " </TD>"
2853 " <TD>"
2854 " <NOSCRIPT>"
2855 " <P>Bad</P>"
2856 " </NOSCRIPT>"
2857 " <INPUT type='text' id='middlename' value='Joe'/>"
2858 " </TD>"
2859 " </TR>"
2860 " <TR>"
2861 " <TD>"
2862 " <SPAN>*</SPAN>"
2863 " <B>Last Name</B>"
2864 " </TD>"
2865 " <TD>"
2866 " <INPUT type='text' id='lastname' value='Smith'/>"
2867 " </TD>"
2868 " </TR>"
2869 " <TR>"
2870 " <TD>"
2871 " <SPAN>*</SPAN>"
2872 " <B>Country</B>"
2873 " </TD>"
2874 " <TD>"
2875 " <SELECT id='country'>"
2876 " <OPTION VALUE='US'>The value should be ignored as label."
2877 " </OPTION>"
2878 " <OPTION VALUE='JP'>JAPAN</OPTION>"
2879 " </SELECT>"
2880 " </TD>"
2881 " </TR>"
2882 " <TR>"
2883 " <TD>"
2884 " <SPAN>*</SPAN>"
2885 " <B>Email</B>"
2886 " </TD>"
2887 " <TD>"
2888 " <!-- This comment should be ignored as inferred label.-->"
2889 " <INPUT type='text' id='email' value='john@example.com'/>"
2890 " </TD>"
2891 " </TR>"
2892 " <TR>"
2893 " <TD></TD>"
2894 " <TD>"
2895 " <INPUT type='submit' name='reply-send' value='Send'/>"
2896 " </TD>"
2897 " </TR>"
2898 "</TABLE>"
2899 "</FORM>",
2900 labels, names, values, control_types);
2903 TEST_F(FormAutofillTest, LabelsInferredFromTableLabels) {
2904 ExpectJohnSmithLabels(
2905 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2906 "<TABLE>"
2907 " <TR>"
2908 " <TD>"
2909 " <LABEL>First name:</LABEL>"
2910 " <INPUT type='text' id='firstname' value='John'/>"
2911 " </TD>"
2912 " </TR>"
2913 " <TR>"
2914 " <TD>"
2915 " <LABEL>Last name:</LABEL>"
2916 " <INPUT type='text' id='lastname' value='Smith'/>"
2917 " </TD>"
2918 " </TR>"
2919 " <TR>"
2920 " <TD>"
2921 " <LABEL>Email:</LABEL>"
2922 " <INPUT type='text' id='email' value='john@example.com'/>"
2923 " </TD>"
2924 " </TR>"
2925 "</TABLE>"
2926 "<INPUT type='submit' name='reply-send' value='Send'/>"
2927 "</FORM>");
2930 TEST_F(FormAutofillTest, LabelsInferredFromTableTDInterveningElements) {
2931 ExpectJohnSmithLabels(
2932 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2933 "<TABLE>"
2934 " <TR>"
2935 " <TD>"
2936 " First name:"
2937 " <BR>"
2938 " <INPUT type='text' id='firstname' value='John'/>"
2939 " </TD>"
2940 " </TR>"
2941 " <TR>"
2942 " <TD>"
2943 " Last name:"
2944 " <BR>"
2945 " <INPUT type='text' id='lastname' value='Smith'/>"
2946 " </TD>"
2947 " </TR>"
2948 " <TR>"
2949 " <TD>"
2950 " Email:"
2951 " <BR>"
2952 " <INPUT type='text' id='email' value='john@example.com'/>"
2953 " </TD>"
2954 " </TR>"
2955 "</TABLE>"
2956 "<INPUT type='submit' name='reply-send' value='Send'/>"
2957 "</FORM>");
2960 // Verify that we correctly infer labels when the label text spans multiple
2961 // adjacent HTML elements, not separated by whitespace.
2962 TEST_F(FormAutofillTest, LabelsInferredFromTableAdjacentElements) {
2963 std::vector<base::string16> labels, names, values;
2965 labels.push_back(ASCIIToUTF16("*First Name"));
2966 names.push_back(ASCIIToUTF16("firstname"));
2967 values.push_back(ASCIIToUTF16("John"));
2969 labels.push_back(ASCIIToUTF16("*Last Name"));
2970 names.push_back(ASCIIToUTF16("lastname"));
2971 values.push_back(ASCIIToUTF16("Smith"));
2973 labels.push_back(ASCIIToUTF16("*Email"));
2974 names.push_back(ASCIIToUTF16("email"));
2975 values.push_back(ASCIIToUTF16("john@example.com"));
2977 ExpectLabels(
2978 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
2979 "<TABLE>"
2980 " <TR>"
2981 " <TD>"
2982 " <SPAN>*</SPAN><B>First Name</B>"
2983 " </TD>"
2984 " <TD>"
2985 " <INPUT type='text' id='firstname' value='John'/>"
2986 " </TD>"
2987 " </TR>"
2988 " <TR>"
2989 " <TD>"
2990 " <SPAN>*</SPAN><B>Last Name</B>"
2991 " </TD>"
2992 " <TD>"
2993 " <INPUT type='text' id='lastname' value='Smith'/>"
2994 " </TD>"
2995 " </TR>"
2996 " <TR>"
2997 " <TD>"
2998 " <SPAN>*</SPAN><B>Email</B>"
2999 " </TD>"
3000 " <TD>"
3001 " <INPUT type='text' id='email' value='john@example.com'/>"
3002 " </TD>"
3003 " </TR>"
3004 " <TR>"
3005 " <TD>"
3006 " <INPUT type='submit' name='reply-send' value='Send'/>"
3007 " </TD>"
3008 " </TR>"
3009 "</TABLE>"
3010 "</FORM>",
3011 labels, names, values);
3014 // Verify that we correctly infer labels when the label text resides in the
3015 // previous row.
3016 TEST_F(FormAutofillTest, LabelsInferredFromTableRow) {
3017 std::vector<base::string16> labels, names, values;
3019 labels.push_back(ASCIIToUTF16("*First Name"));
3020 names.push_back(ASCIIToUTF16("firstname"));
3021 values.push_back(ASCIIToUTF16("John"));
3023 labels.push_back(ASCIIToUTF16("*Last Name"));
3024 names.push_back(ASCIIToUTF16("lastname"));
3025 values.push_back(ASCIIToUTF16("Smith"));
3027 labels.push_back(ASCIIToUTF16("*Email"));
3028 names.push_back(ASCIIToUTF16("email"));
3029 values.push_back(ASCIIToUTF16("john@example.com"));
3031 labels.push_back(ASCIIToUTF16("NAME"));
3032 names.push_back(ASCIIToUTF16("name2"));
3033 values.push_back(ASCIIToUTF16("John Smith"));
3035 labels.push_back(ASCIIToUTF16("EMAIL"));
3036 names.push_back(ASCIIToUTF16("email2"));
3037 values.push_back(ASCIIToUTF16("john@example2.com"));
3039 labels.push_back(ASCIIToUTF16("Phone"));
3040 names.push_back(ASCIIToUTF16("phone1"));
3041 values.push_back(ASCIIToUTF16("123"));
3043 labels.push_back(ASCIIToUTF16("Phone"));
3044 names.push_back(ASCIIToUTF16("phone2"));
3045 values.push_back(ASCIIToUTF16("456"));
3047 labels.push_back(ASCIIToUTF16("Phone"));
3048 names.push_back(ASCIIToUTF16("phone3"));
3049 values.push_back(ASCIIToUTF16("7890"));
3051 labels.push_back(ASCIIToUTF16("Credit Card Number"));
3052 names.push_back(ASCIIToUTF16("ccnumber"));
3053 values.push_back(ASCIIToUTF16("4444555544445555"));
3055 ExpectLabels(
3056 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3057 "<TABLE>"
3058 " <TR>"
3059 " <TD>*First Name</TD>"
3060 " <TD>*Last Name</TD>"
3061 " <TD>*Email</TD>"
3062 " </TR>"
3063 " <TR>"
3064 " <TD>"
3065 " <INPUT type='text' id='firstname' value='John'/>"
3066 " </TD>"
3067 " <TD>"
3068 " <INPUT type='text' id='lastname' value='Smith'/>"
3069 " </TD>"
3070 " <TD>"
3071 " <INPUT type='text' id='email' value='john@example.com'/>"
3072 " </TD>"
3073 " </TR>"
3074 " <TR>"
3075 " <TD colspan='2'>NAME</TD>"
3076 " <TD>EMAIL</TD>"
3077 " </TR>"
3078 " <TR>"
3079 " <TD colspan='2'>"
3080 " <INPUT type='text' id='name2' value='John Smith'/>"
3081 " </TD>"
3082 " <TD>"
3083 " <INPUT type='text' id='email2' value='john@example2.com'/>"
3084 " </TD>"
3085 " </TR>"
3086 " <TR>"
3087 " <TD>Phone</TD>"
3088 " </TR>"
3089 " <TR>"
3090 " <TD>"
3091 " <INPUT type='text' id='phone1' value='123'/>"
3092 " </TD>"
3093 " <TD>"
3094 " <INPUT type='text' id='phone2' value='456'/>"
3095 " </TD>"
3096 " <TD>"
3097 " <INPUT type='text' id='phone3' value='7890'/>"
3098 " </TD>"
3099 " </TR>"
3100 " <TR>"
3101 " <TH>"
3102 " Credit Card Number"
3103 " </TH>"
3104 " </TR>"
3105 " <TR>"
3106 " <TD>"
3107 " <INPUT type='text' name='ccnumber' value='4444555544445555'/>"
3108 " </TD>"
3109 " </TR>"
3110 " <TR>"
3111 " <TD>"
3112 " <INPUT type='submit' name='reply-send' value='Send'/>"
3113 " </TD>"
3114 " </TR>"
3115 "</TABLE>",
3116 labels, names, values);
3119 // Verify that we correctly infer labels when enclosed within a list item.
3120 TEST_F(FormAutofillTest, LabelsInferredFromListItem) {
3121 std::vector<base::string16> labels, names, values;
3123 labels.push_back(ASCIIToUTF16("* Home Phone"));
3124 names.push_back(ASCIIToUTF16("areacode"));
3125 values.push_back(ASCIIToUTF16("415"));
3127 labels.push_back(ASCIIToUTF16("* Home Phone"));
3128 names.push_back(ASCIIToUTF16("prefix"));
3129 values.push_back(ASCIIToUTF16("555"));
3131 labels.push_back(ASCIIToUTF16("* Home Phone"));
3132 names.push_back(ASCIIToUTF16("suffix"));
3133 values.push_back(ASCIIToUTF16("1212"));
3135 ExpectLabels(
3136 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3137 "<DIV>"
3138 " <LI>"
3139 " <SPAN>Bogus</SPAN>"
3140 " </LI>"
3141 " <LI>"
3142 " <LABEL><EM>*</EM> Home Phone</LABEL>"
3143 " <INPUT type='text' id='areacode' value='415'/>"
3144 " <INPUT type='text' id='prefix' value='555'/>"
3145 " <INPUT type='text' id='suffix' value='1212'/>"
3146 " </LI>"
3147 " <LI>"
3148 " <INPUT type='submit' name='reply-send' value='Send'/>"
3149 " </LI>"
3150 "</DIV>"
3151 "</FORM>",
3152 labels, names, values);
3155 TEST_F(FormAutofillTest, LabelsInferredFromDefinitionList) {
3156 std::vector<base::string16> labels, names, values;
3158 labels.push_back(ASCIIToUTF16("* First name: Bogus"));
3159 names.push_back(ASCIIToUTF16("firstname"));
3160 values.push_back(ASCIIToUTF16("John"));
3162 labels.push_back(ASCIIToUTF16("Last name:"));
3163 names.push_back(ASCIIToUTF16("lastname"));
3164 values.push_back(ASCIIToUTF16("Smith"));
3166 labels.push_back(ASCIIToUTF16("Email:"));
3167 names.push_back(ASCIIToUTF16("email"));
3168 values.push_back(ASCIIToUTF16("john@example.com"));
3170 ExpectLabels(
3171 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3172 "<DL>"
3173 " <DT>"
3174 " <SPAN>"
3175 " *"
3176 " </SPAN>"
3177 " <SPAN>"
3178 " First name:"
3179 " </SPAN>"
3180 " <SPAN>"
3181 " Bogus"
3182 " </SPAN>"
3183 " </DT>"
3184 " <DD>"
3185 " <FONT>"
3186 " <INPUT type='text' id='firstname' value='John'/>"
3187 " </FONT>"
3188 " </DD>"
3189 " <DT>"
3190 " <SPAN>"
3191 " Last name:"
3192 " </SPAN>"
3193 " </DT>"
3194 " <DD>"
3195 " <FONT>"
3196 " <INPUT type='text' id='lastname' value='Smith'/>"
3197 " </FONT>"
3198 " </DD>"
3199 " <DT>"
3200 " <SPAN>"
3201 " Email:"
3202 " </SPAN>"
3203 " </DT>"
3204 " <DD>"
3205 " <FONT>"
3206 " <INPUT type='text' id='email' value='john@example.com'/>"
3207 " </FONT>"
3208 " </DD>"
3209 " <DT></DT>"
3210 " <DD>"
3211 " <INPUT type='submit' name='reply-send' value='Send'/>"
3212 " </DD>"
3213 "</DL>"
3214 "</FORM>",
3215 labels, names, values);
3218 TEST_F(FormAutofillTest, LabelsInferredWithSameName) {
3219 std::vector<base::string16> labels, names, values;
3221 labels.push_back(ASCIIToUTF16("Address Line 1:"));
3222 names.push_back(ASCIIToUTF16("Address"));
3223 values.push_back(base::string16());
3225 labels.push_back(ASCIIToUTF16("Address Line 2:"));
3226 names.push_back(ASCIIToUTF16("Address"));
3227 values.push_back(base::string16());
3229 labels.push_back(ASCIIToUTF16("Address Line 3:"));
3230 names.push_back(ASCIIToUTF16("Address"));
3231 values.push_back(base::string16());
3233 ExpectLabels(
3234 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3235 " Address Line 1:"
3236 " <INPUT type='text' name='Address'/>"
3237 " Address Line 2:"
3238 " <INPUT type='text' name='Address'/>"
3239 " Address Line 3:"
3240 " <INPUT type='text' name='Address'/>"
3241 " <INPUT type='submit' name='reply-send' value='Send'/>"
3242 "</FORM>",
3243 labels, names, values);
3246 TEST_F(FormAutofillTest, LabelsInferredWithImageTags) {
3247 std::vector<base::string16> labels, names, values;
3249 labels.push_back(ASCIIToUTF16("Phone:"));
3250 names.push_back(ASCIIToUTF16("dayphone1"));
3251 values.push_back(base::string16());
3253 labels.push_back(ASCIIToUTF16("-"));
3254 names.push_back(ASCIIToUTF16("dayphone2"));
3255 values.push_back(base::string16());
3257 labels.push_back(ASCIIToUTF16("-"));
3258 names.push_back(ASCIIToUTF16("dayphone3"));
3259 values.push_back(base::string16());
3261 labels.push_back(ASCIIToUTF16("ext.:"));
3262 names.push_back(ASCIIToUTF16("dayphone4"));
3263 values.push_back(base::string16());
3265 labels.push_back(base::string16());
3266 names.push_back(ASCIIToUTF16("dummy"));
3267 values.push_back(base::string16());
3269 ExpectLabels(
3270 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3271 " Phone:"
3272 " <input type='text' name='dayphone1'>"
3273 " <img/>"
3274 " -"
3275 " <img/>"
3276 " <input type='text' name='dayphone2'>"
3277 " <img/>"
3278 " -"
3279 " <img/>"
3280 " <input type='text' name='dayphone3'>"
3281 " ext.:"
3282 " <input type='text' name='dayphone4'>"
3283 " <input type='text' name='dummy'>"
3284 " <input type='submit' name='reply-send' value='Send'>"
3285 "</FORM>",
3286 labels, names, values);
3289 TEST_F(FormAutofillTest, LabelsInferredFromDivTable) {
3290 ExpectJohnSmithLabels(
3291 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3292 "<DIV>First name:<BR>"
3293 " <SPAN>"
3294 " <INPUT type='text' name='firstname' value='John'>"
3295 " </SPAN>"
3296 "</DIV>"
3297 "<DIV>Last name:<BR>"
3298 " <SPAN>"
3299 " <INPUT type='text' name='lastname' value='Smith'>"
3300 " </SPAN>"
3301 "</DIV>"
3302 "<DIV>Email:<BR>"
3303 " <SPAN>"
3304 " <INPUT type='text' name='email' value='john@example.com'>"
3305 " </SPAN>"
3306 "</DIV>"
3307 "<input type='submit' name='reply-send' value='Send'>"
3308 "</FORM>");
3311 TEST_F(FormAutofillTest, LabelsInferredFromDivSiblingTable) {
3312 ExpectJohnSmithLabels(
3313 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3314 "<DIV>First name:</DIV>"
3315 "<DIV>"
3316 " <SPAN>"
3317 " <INPUT type='text' name='firstname' value='John'>"
3318 " </SPAN>"
3319 "</DIV>"
3320 "<DIV>Last name:</DIV>"
3321 "<DIV>"
3322 " <SPAN>"
3323 " <INPUT type='text' name='lastname' value='Smith'>"
3324 " </SPAN>"
3325 "</DIV>"
3326 "<DIV>Email:</DIV>"
3327 "<DIV>"
3328 " <SPAN>"
3329 " <INPUT type='text' name='email' value='john@example.com'>"
3330 " </SPAN>"
3331 "</DIV>"
3332 "<input type='submit' name='reply-send' value='Send'>"
3333 "</FORM>");
3336 TEST_F(FormAutofillTest, LabelsInferredFromLabelInDivTable) {
3337 ExpectJohnSmithLabels(
3338 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3339 "<LABEL>First name:</LABEL>"
3340 "<LABEL for='lastname'>Last name:</LABEL>"
3341 "<DIV>"
3342 " <INPUT type='text' id='firstname' value='John'>"
3343 "</DIV>"
3344 "<DIV>"
3345 " <INPUT type='text' id='lastname' value='Smith'>"
3346 "</DIV>"
3347 "<LABEL>Email:</LABEL>"
3348 "<DIV>"
3349 " <SPAN>"
3350 " <INPUT type='text' id='email' value='john@example.com'>"
3351 " </SPAN>"
3352 "</DIV>"
3353 "<input type='submit' name='reply-send' value='Send'>"
3354 "</FORM>");
3357 TEST_F(FormAutofillTest, LabelsInferredFromDefinitionListRatherThanDivTable) {
3358 ExpectJohnSmithLabels(
3359 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3360 "<DIV>This is not a label.<BR>"
3361 "<DL>"
3362 " <DT>"
3363 " <SPAN>"
3364 " First name:"
3365 " </SPAN>"
3366 " </DT>"
3367 " <DD>"
3368 " <FONT>"
3369 " <INPUT type='text' id='firstname' value='John'/>"
3370 " </FONT>"
3371 " </DD>"
3372 " <DT>"
3373 " <SPAN>"
3374 " Last name:"
3375 " </SPAN>"
3376 " </DT>"
3377 " <DD>"
3378 " <FONT>"
3379 " <INPUT type='text' id='lastname' value='Smith'/>"
3380 " </FONT>"
3381 " </DD>"
3382 " <DT>"
3383 " <SPAN>"
3384 " Email:"
3385 " </SPAN>"
3386 " </DT>"
3387 " <DD>"
3388 " <FONT>"
3389 " <INPUT type='text' id='email' value='john@example.com'/>"
3390 " </FONT>"
3391 " </DD>"
3392 " <DT></DT>"
3393 " <DD>"
3394 " <INPUT type='submit' name='reply-send' value='Send'/>"
3395 " </DD>"
3396 "</DL>"
3397 "</DIV>"
3398 "</FORM>");
3401 TEST_F(FormAutofillTest, FillFormMaxLength) {
3402 TestFillFormMaxLength(
3403 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3404 " <INPUT type='text' id='firstname' maxlength='5'/>"
3405 " <INPUT type='text' id='lastname' maxlength='7'/>"
3406 " <INPUT type='text' id='email' maxlength='9'/>"
3407 " <INPUT type='submit' name='reply-send' value='Send'/>"
3408 "</FORM>",
3409 false);
3412 TEST_F(FormAutofillTest, FillFormMaxLengthForUnownedForm) {
3413 TestFillFormMaxLength(
3414 "<HEAD><TITLE>delivery recipient info</TITLE></HEAD>"
3415 "<INPUT type='text' id='firstname' maxlength='5'/>"
3416 "<INPUT type='text' id='lastname' maxlength='7'/>"
3417 "<INPUT type='text' id='email' maxlength='9'/>"
3418 "<INPUT type='submit' name='reply-send' value='Send'/>",
3419 true);
3422 // This test uses negative values of the maxlength attribute for input elements.
3423 // In this case, the maxlength of the input elements is set to the default
3424 // maxlength (defined in WebKit.)
3425 TEST_F(FormAutofillTest, FillFormNegativeMaxLength) {
3426 TestFillFormNegativeMaxLength(
3427 "<HEAD><TITLE>delivery recipient info</TITLE></HEAD>"
3428 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3429 " <INPUT type='text' id='firstname' maxlength='-1'/>"
3430 " <INPUT type='text' id='lastname' maxlength='-10'/>"
3431 " <INPUT type='text' id='email' maxlength='-13'/>"
3432 " <INPUT type='submit' name='reply-send' value='Send'/>"
3433 "</FORM>",
3434 false);
3437 TEST_F(FormAutofillTest, FillFormNegativeMaxLengthForUnownedForm) {
3438 TestFillFormNegativeMaxLength(
3439 "<HEAD><TITLE>delivery recipient info</TITLE></HEAD>"
3440 "<INPUT type='text' id='firstname' maxlength='-1'/>"
3441 "<INPUT type='text' id='lastname' maxlength='-10'/>"
3442 "<INPUT type='text' id='email' maxlength='-13'/>"
3443 "<INPUT type='submit' name='reply-send' value='Send'/>",
3444 true);
3447 TEST_F(FormAutofillTest, FillFormEmptyName) {
3448 TestFillFormEmptyName(
3449 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3450 " <INPUT type='text' id='firstname'/>"
3451 " <INPUT type='text' id='lastname'/>"
3452 " <INPUT type='text' id='email'/>"
3453 " <INPUT type='submit' value='Send'/>"
3454 "</FORM>",
3455 false);
3458 TEST_F(FormAutofillTest, FillFormEmptyNameForUnownedForm) {
3459 TestFillFormEmptyName(
3460 "<HEAD><TITLE>delivery recipient info</TITLE></HEAD>"
3461 "<INPUT type='text' id='firstname'/>"
3462 "<INPUT type='text' id='lastname'/>"
3463 "<INPUT type='text' id='email'/>"
3464 "<INPUT type='submit' value='Send'/>",
3465 true);
3468 TEST_F(FormAutofillTest, FillFormEmptyFormNames) {
3469 TestFillFormEmptyFormNames(
3470 "<FORM action='http://buh.com' method='post'>"
3471 " <INPUT type='text' id='firstname'/>"
3472 " <INPUT type='text' id='middlename'/>"
3473 " <INPUT type='text' id='lastname'/>"
3474 " <INPUT type='submit' value='Send'/>"
3475 "</FORM>"
3476 "<FORM action='http://abc.com' method='post'>"
3477 " <INPUT type='text' id='apple'/>"
3478 " <INPUT type='text' id='banana'/>"
3479 " <INPUT type='text' id='cantelope'/>"
3480 " <INPUT type='submit' value='Send'/>"
3481 "</FORM>",
3482 false);
3485 TEST_F(FormAutofillTest, FillFormEmptyFormNamesForUnownedForm) {
3486 TestFillFormEmptyFormNames(
3487 "<HEAD><TITLE>enter delivery preferences</TITLE></HEAD>"
3488 "<INPUT type='text' id='firstname'/>"
3489 "<INPUT type='text' id='middlename'/>"
3490 "<INPUT type='text' id='lastname'/>"
3491 "<INPUT type='text' id='apple'/>"
3492 "<INPUT type='text' id='banana'/>"
3493 "<INPUT type='text' id='cantelope'/>"
3494 "<INPUT type='submit' value='Send'/>",
3495 true);
3498 TEST_F(FormAutofillTest, ThreePartPhone) {
3499 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
3500 " Phone:"
3501 " <input type='text' name='dayphone1'>"
3502 " -"
3503 " <input type='text' name='dayphone2'>"
3504 " -"
3505 " <input type='text' name='dayphone3'>"
3506 " ext.:"
3507 " <input type='text' name='dayphone4'>"
3508 " <input type='submit' name='reply-send' value='Send'>"
3509 "</FORM>");
3511 WebFrame* frame = GetMainFrame();
3512 ASSERT_NE(nullptr, frame);
3514 WebVector<WebFormElement> forms;
3515 frame->document().forms(forms);
3516 ASSERT_EQ(1U, forms.size());
3518 FormData form;
3519 EXPECT_TRUE(WebFormElementToFormData(forms[0],
3520 WebFormControlElement(),
3521 EXTRACT_VALUE,
3522 &form,
3523 nullptr));
3524 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
3525 EXPECT_EQ(GURL(frame->document().url()), form.origin);
3526 EXPECT_FALSE(form.origin.is_empty());
3527 EXPECT_EQ(GURL("http://cnn.com"), form.action);
3529 const std::vector<FormFieldData>& fields = form.fields;
3530 ASSERT_EQ(4U, fields.size());
3532 FormFieldData expected;
3533 expected.form_control_type = "text";
3534 expected.max_length = WebInputElement::defaultMaxLength();
3536 expected.label = ASCIIToUTF16("Phone:");
3537 expected.name = ASCIIToUTF16("dayphone1");
3538 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
3540 expected.label = ASCIIToUTF16("-");
3541 expected.name = ASCIIToUTF16("dayphone2");
3542 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
3544 expected.label = ASCIIToUTF16("-");
3545 expected.name = ASCIIToUTF16("dayphone3");
3546 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
3548 expected.label = ASCIIToUTF16("ext.:");
3549 expected.name = ASCIIToUTF16("dayphone4");
3550 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
3554 TEST_F(FormAutofillTest, MaxLengthFields) {
3555 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
3556 " Phone:"
3557 " <input type='text' maxlength='3' name='dayphone1'>"
3558 " -"
3559 " <input type='text' maxlength='3' name='dayphone2'>"
3560 " -"
3561 " <input type='text' maxlength='4' size='5'"
3562 " name='dayphone3'>"
3563 " ext.:"
3564 " <input type='text' maxlength='5' name='dayphone4'>"
3565 " <input type='text' name='default1'>"
3566 " <input type='text' maxlength='-1' name='invalid1'>"
3567 " <input type='submit' name='reply-send' value='Send'>"
3568 "</FORM>");
3570 WebFrame* frame = GetMainFrame();
3571 ASSERT_NE(nullptr, frame);
3573 WebVector<WebFormElement> forms;
3574 frame->document().forms(forms);
3575 ASSERT_EQ(1U, forms.size());
3577 FormData form;
3578 EXPECT_TRUE(WebFormElementToFormData(forms[0],
3579 WebFormControlElement(),
3580 EXTRACT_VALUE,
3581 &form,
3582 nullptr));
3583 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
3584 EXPECT_EQ(GURL(frame->document().url()), form.origin);
3585 EXPECT_EQ(GURL("http://cnn.com"), form.action);
3587 const std::vector<FormFieldData>& fields = form.fields;
3588 ASSERT_EQ(6U, fields.size());
3590 FormFieldData expected;
3591 expected.form_control_type = "text";
3593 expected.label = ASCIIToUTF16("Phone:");
3594 expected.name = ASCIIToUTF16("dayphone1");
3595 expected.max_length = 3;
3596 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
3598 expected.label = ASCIIToUTF16("-");
3599 expected.name = ASCIIToUTF16("dayphone2");
3600 expected.max_length = 3;
3601 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
3603 expected.label = ASCIIToUTF16("-");
3604 expected.name = ASCIIToUTF16("dayphone3");
3605 expected.max_length = 4;
3606 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
3608 expected.label = ASCIIToUTF16("ext.:");
3609 expected.name = ASCIIToUTF16("dayphone4");
3610 expected.max_length = 5;
3611 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
3613 // When unspecified |size|, default is returned.
3614 expected.label.clear();
3615 expected.name = ASCIIToUTF16("default1");
3616 expected.max_length = WebInputElement::defaultMaxLength();
3617 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[4]);
3619 // When invalid |size|, default is returned.
3620 expected.label.clear();
3621 expected.name = ASCIIToUTF16("invalid1");
3622 expected.max_length = WebInputElement::defaultMaxLength();
3623 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[5]);
3626 // This test re-creates the experience of typing in a field then selecting a
3627 // profile from the Autofill suggestions popup. The field that is being typed
3628 // into should be filled even though it's not technically empty.
3629 TEST_F(FormAutofillTest, FillFormNonEmptyField) {
3630 TestFillFormNonEmptyField(
3631 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3632 " <INPUT type='text' id='firstname'/>"
3633 " <INPUT type='text' id='lastname'/>"
3634 " <INPUT type='text' id='email'/>"
3635 " <INPUT type='submit' value='Send'/>"
3636 "</FORM>",
3637 false);
3640 TEST_F(FormAutofillTest, FillFormNonEmptyFieldForUnownedForm) {
3641 TestFillFormNonEmptyField(
3642 "<HEAD><TITLE>delivery recipient info</TITLE></HEAD>"
3643 "<INPUT type='text' id='firstname'/>"
3644 "<INPUT type='text' id='lastname'/>"
3645 "<INPUT type='text' id='email'/>"
3646 "<INPUT type='submit' value='Send'/>",
3647 true);
3650 TEST_F(FormAutofillTest, ClearFormWithNode) {
3651 TestClearFormWithNode(
3652 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3653 " <INPUT type='text' id='firstname' value='Wyatt'/>"
3654 " <INPUT type='text' id='lastname' value='Earp'/>"
3655 " <INPUT type='text' autocomplete='off' id='noAC' value='one'/>"
3656 " <INPUT type='text' id='notenabled' disabled='disabled'>"
3657 " <INPUT type='month' id='month' value='2012-11'>"
3658 " <INPUT type='month' id='month-disabled' value='2012-11'"
3659 " disabled='disabled'>"
3660 " <TEXTAREA id='textarea'>Apple.</TEXTAREA>"
3661 " <TEXTAREA id='textarea-disabled' disabled='disabled'>"
3662 " Banana!"
3663 " </TEXTAREA>"
3664 " <TEXTAREA id='textarea-noAC' autocomplete='off'>Carrot?</TEXTAREA>"
3665 " <INPUT type='submit' value='Send'/>"
3666 "</FORM>",
3667 false);
3670 TEST_F(FormAutofillTest, ClearFormWithNodeForUnownedForm) {
3671 TestClearFormWithNode(
3672 "<HEAD><TITLE>store checkout</TITLE></HEAD>"
3673 " <!-- Indented on purpose //-->"
3674 " <INPUT type='text' id='firstname' value='Wyatt'/>"
3675 " <INPUT type='text' id='lastname' value='Earp'/>"
3676 " <INPUT type='text' autocomplete='off' id='noAC' value='one'/>"
3677 " <INPUT type='text' id='notenabled' disabled='disabled'>"
3678 " <INPUT type='month' id='month' value='2012-11'>"
3679 " <INPUT type='month' id='month-disabled' value='2012-11'"
3680 " disabled='disabled'>"
3681 " <TEXTAREA id='textarea'>Apple.</TEXTAREA>"
3682 " <TEXTAREA id='textarea-disabled' disabled='disabled'>"
3683 " Banana!"
3684 " </TEXTAREA>"
3685 " <TEXTAREA id='textarea-noAC' autocomplete='off'>Carrot?</TEXTAREA>"
3686 " <INPUT type='submit' value='Send'/>",
3687 true);
3690 TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOne) {
3691 TestClearFormWithNodeContainingSelectOne(
3692 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3693 " <INPUT type='text' id='firstname' value='Wyatt'/>"
3694 " <INPUT type='text' id='lastname' value='Earp'/>"
3695 " <SELECT id='state' name='state'>"
3696 " <OPTION selected>?</OPTION>"
3697 " <OPTION>AA</OPTION>"
3698 " <OPTION>AE</OPTION>"
3699 " <OPTION>AK</OPTION>"
3700 " </SELECT>"
3701 " <INPUT type='submit' value='Send'/>"
3702 "</FORM>",
3703 false);
3706 TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOneForUnownedForm) {
3707 TestClearFormWithNodeContainingSelectOne(
3708 "<HEAD><TITLE>store checkout</TITLE></HEAD>"
3709 "<INPUT type='text' id='firstname' value='Wyatt'/>"
3710 "<INPUT type='text' id='lastname' value='Earp'/>"
3711 "<SELECT id='state' name='state'>"
3712 " <OPTION selected>?</OPTION>"
3713 " <OPTION>AA</OPTION>"
3714 " <OPTION>AE</OPTION>"
3715 " <OPTION>AK</OPTION>"
3716 "</SELECT>"
3717 "<INPUT type='submit' value='Send'/>",
3718 true);
3721 TEST_F(FormAutofillTest, ClearPreviewedFormWithElement) {
3722 TestClearPreviewedFormWithElement(
3723 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3724 " <INPUT type='text' id='firstname' value='Wyatt'/>"
3725 " <INPUT type='text' id='lastname'/>"
3726 " <INPUT type='text' id='email'/>"
3727 " <INPUT type='email' id='email2'/>"
3728 " <INPUT type='tel' id='phone'/>"
3729 " <INPUT type='submit' value='Send'/>"
3730 "</FORM>");
3733 TEST_F(FormAutofillTest, ClearPreviewedFormWithElementForUnownedForm) {
3734 TestClearPreviewedFormWithElement(
3735 "<HEAD><TITLE>store checkout</TITLE></HEAD>"
3736 "<INPUT type='text' id='firstname' value='Wyatt'/>"
3737 "<INPUT type='text' id='lastname'/>"
3738 "<INPUT type='text' id='email'/>"
3739 "<INPUT type='email' id='email2'/>"
3740 "<INPUT type='tel' id='phone'/>"
3741 "<INPUT type='submit' value='Send'/>");
3744 TEST_F(FormAutofillTest, ClearPreviewedFormWithNonEmptyInitiatingNode) {
3745 TestClearPreviewedFormWithNonEmptyInitiatingNode(
3746 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3747 " <INPUT type='text' id='firstname' value='W'/>"
3748 " <INPUT type='text' id='lastname'/>"
3749 " <INPUT type='text' id='email'/>"
3750 " <INPUT type='email' id='email2'/>"
3751 " <INPUT type='tel' id='phone'/>"
3752 " <INPUT type='submit' value='Send'/>"
3753 "</FORM>");
3756 TEST_F(FormAutofillTest,
3757 ClearPreviewedFormWithNonEmptyInitiatingNodeForUnownedForm) {
3758 TestClearPreviewedFormWithNonEmptyInitiatingNode(
3759 "<HEAD><TITLE>shipping details</TITLE></HEAD>"
3760 "<INPUT type='text' id='firstname' value='W'/>"
3761 "<INPUT type='text' id='lastname'/>"
3762 "<INPUT type='text' id='email'/>"
3763 "<INPUT type='email' id='email2'/>"
3764 "<INPUT type='tel' id='phone'/>"
3765 "<INPUT type='submit' value='Send'/>");
3768 TEST_F(FormAutofillTest, ClearPreviewedFormWithAutofilledInitiatingNode) {
3769 TestClearPreviewedFormWithAutofilledInitiatingNode(
3770 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3771 " <INPUT type='text' id='firstname' value='W'/>"
3772 " <INPUT type='text' id='lastname'/>"
3773 " <INPUT type='text' id='email'/>"
3774 " <INPUT type='email' id='email2'/>"
3775 " <INPUT type='tel' id='phone'/>"
3776 " <INPUT type='submit' value='Send'/>"
3777 "</FORM>");
3780 TEST_F(FormAutofillTest,
3781 ClearPreviewedFormWithAutofilledInitiatingNodeForUnownedForm) {
3782 TestClearPreviewedFormWithAutofilledInitiatingNode(
3783 "<HEAD><TITLE>shipping details</TITLE></HEAD>"
3784 "<INPUT type='text' id='firstname' value='W'/>"
3785 "<INPUT type='text' id='lastname'/>"
3786 "<INPUT type='text' id='email'/>"
3787 "<INPUT type='email' id='email2'/>"
3788 "<INPUT type='tel' id='phone'/>"
3789 "<INPUT type='submit' value='Send'/>");
3792 // Autofill's "Clear Form" should clear only autofilled fields
3793 TEST_F(FormAutofillTest, ClearOnlyAutofilledFields) {
3794 TestClearOnlyAutofilledFields(
3795 "<FORM name='TestForm' action='http://buh.com' method='post'>"
3796 " <INPUT type='text' id='firstname' value='Wyatt'/>"
3797 " <INPUT type='text' id='lastname' value='Earp'/>"
3798 " <INPUT type='email' id='email' value='wyatt@earp.com'/>"
3799 " <INPUT type='tel' id='phone' value='650-777-9999'/>"
3800 " <INPUT type='submit' value='Send'/>"
3801 "</FORM>");
3804 TEST_F(FormAutofillTest, ClearOnlyAutofilledFieldsForUnownedForm) {
3805 TestClearOnlyAutofilledFields(
3806 "<HEAD><TITLE>shipping details</TITLE></HEAD>"
3807 "<INPUT type='text' id='firstname' value='Wyatt'/>"
3808 "<INPUT type='text' id='lastname' value='Earp'/>"
3809 "<INPUT type='email' id='email' value='wyatt@earp.com'/>"
3810 "<INPUT type='tel' id='phone' value='650-777-9999'/>"
3811 "<INPUT type='submit' value='Send'/>");
3814 // If we have multiple labels per id, the labels concatenated into label string.
3815 TEST_F(FormAutofillTest, MultipleLabelsPerElement) {
3816 std::vector<base::string16> labels, names, values;
3818 labels.push_back(ASCIIToUTF16("First Name:"));
3819 names.push_back(ASCIIToUTF16("firstname"));
3820 values.push_back(ASCIIToUTF16("John"));
3822 labels.push_back(ASCIIToUTF16("Last Name:"));
3823 names.push_back(ASCIIToUTF16("lastname"));
3824 values.push_back(ASCIIToUTF16("Smith"));
3826 labels.push_back(ASCIIToUTF16("Email: xxx@yyy.com"));
3827 names.push_back(ASCIIToUTF16("email"));
3828 values.push_back(ASCIIToUTF16("john@example.com"));
3830 ExpectLabels(
3831 "<FORM name='TestForm' action='http://cnn.com' method='post'>"
3832 " <LABEL for='firstname'> First Name: </LABEL>"
3833 " <LABEL for='firstname'></LABEL>"
3834 " <INPUT type='text' id='firstname' value='John'/>"
3835 " <LABEL for='lastname'></LABEL>"
3836 " <LABEL for='lastname'> Last Name: </LABEL>"
3837 " <INPUT type='text' id='lastname' value='Smith'/>"
3838 " <LABEL for='email'> Email: </LABEL>"
3839 " <LABEL for='email'> xxx@yyy.com </LABEL>"
3840 " <INPUT type='text' id='email' value='john@example.com'/>"
3841 " <INPUT type='submit' name='reply-send' value='Send'/>"
3842 "</FORM>",
3843 labels, names, values);
3846 TEST_F(FormAutofillTest, ClickElement) {
3847 LoadHTML("<BUTTON id='link'>Button</BUTTON>"
3848 "<BUTTON name='button'>Button</BUTTON>");
3849 WebFrame* frame = GetMainFrame();
3850 ASSERT_NE(nullptr, frame);
3852 // Successful retrieval by id.
3853 WebElementDescriptor clicker;
3854 clicker.retrieval_method = WebElementDescriptor::ID;
3855 clicker.descriptor = "link";
3856 EXPECT_TRUE(ClickElement(frame->document(), clicker));
3858 // Successful retrieval by css selector.
3859 clicker.retrieval_method = WebElementDescriptor::CSS_SELECTOR;
3860 clicker.descriptor = "button[name='button']";
3861 EXPECT_TRUE(ClickElement(frame->document(), clicker));
3863 // Unsuccessful retrieval due to invalid CSS selector.
3864 clicker.descriptor = "^*&";
3865 EXPECT_FALSE(ClickElement(frame->document(), clicker));
3867 // Unsuccessful retrieval because element does not exist.
3868 clicker.descriptor = "#junk";
3869 EXPECT_FALSE(ClickElement(frame->document(), clicker));
3872 TEST_F(FormAutofillTest, SelectOneAsText) {
3873 LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>"
3874 " <INPUT type='text' id='firstname' value='John'/>"
3875 " <INPUT type='text' id='lastname' value='Smith'/>"
3876 " <SELECT id='country'>"
3877 " <OPTION value='AF'>Afghanistan</OPTION>"
3878 " <OPTION value='AL'>Albania</OPTION>"
3879 " <OPTION value='DZ'>Algeria</OPTION>"
3880 " </SELECT>"
3881 " <INPUT type='submit' name='reply-send' value='Send'/>"
3882 "</FORM>");
3884 WebFrame* frame = GetMainFrame();
3885 ASSERT_NE(nullptr, frame);
3887 // Set the value of the select-one.
3888 WebSelectElement select_element =
3889 frame->document().getElementById("country").to<WebSelectElement>();
3890 select_element.setValue(WebString::fromUTF8("AL"));
3892 WebVector<WebFormElement> forms;
3893 frame->document().forms(forms);
3894 ASSERT_EQ(1U, forms.size());
3896 FormData form;
3898 // Extract the country select-one value as text.
3899 EXPECT_TRUE(WebFormElementToFormData(
3900 forms[0], WebFormControlElement(),
3901 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTION_TEXT), &form,
3902 nullptr));
3903 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
3904 EXPECT_EQ(GURL(frame->document().url()), form.origin);
3905 EXPECT_EQ(GURL("http://cnn.com"), form.action);
3907 const std::vector<FormFieldData>& fields = form.fields;
3908 ASSERT_EQ(3U, fields.size());
3910 FormFieldData expected;
3912 expected.name = ASCIIToUTF16("firstname");
3913 expected.value = ASCIIToUTF16("John");
3914 expected.form_control_type = "text";
3915 expected.max_length = WebInputElement::defaultMaxLength();
3916 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
3918 expected.name = ASCIIToUTF16("lastname");
3919 expected.value = ASCIIToUTF16("Smith");
3920 expected.form_control_type = "text";
3921 expected.max_length = WebInputElement::defaultMaxLength();
3922 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
3924 expected.name = ASCIIToUTF16("country");
3925 expected.value = ASCIIToUTF16("Albania");
3926 expected.form_control_type = "select-one";
3927 expected.max_length = 0;
3928 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
3930 form.fields.clear();
3931 // Extract the country select-one value as value.
3932 EXPECT_TRUE(WebFormElementToFormData(forms[0],
3933 WebFormControlElement(),
3934 EXTRACT_VALUE,
3935 &form,
3936 nullptr));
3937 EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
3938 EXPECT_EQ(GURL(frame->document().url()), form.origin);
3939 EXPECT_EQ(GURL("http://cnn.com"), form.action);
3941 ASSERT_EQ(3U, fields.size());
3943 expected.name = ASCIIToUTF16("firstname");
3944 expected.value = ASCIIToUTF16("John");
3945 expected.form_control_type = "text";
3946 expected.max_length = WebInputElement::defaultMaxLength();
3947 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
3949 expected.name = ASCIIToUTF16("lastname");
3950 expected.value = ASCIIToUTF16("Smith");
3951 expected.form_control_type = "text";
3952 expected.max_length = WebInputElement::defaultMaxLength();
3953 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
3955 expected.name = ASCIIToUTF16("country");
3956 expected.value = ASCIIToUTF16("AL");
3957 expected.form_control_type = "select-one";
3958 expected.max_length = 0;
3959 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
3962 TEST_F(FormAutofillTest,
3963 UnownedFormElementsAndFieldSetsToFormDataFieldsets) {
3964 std::vector<WebElement> fieldsets;
3965 std::vector<WebFormControlElement> control_elements;
3967 const ExtractMask extract_mask =
3968 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
3970 LoadHTML("<HEAD><TITLE>delivery info</TITLE></HEAD>"
3971 "<DIV>"
3972 " <FIELDSET>"
3973 " <LABEL for='firstname'>First name:</LABEL>"
3974 " <LABEL for='lastname'>Last name:</LABEL>"
3975 " <INPUT type='text' id='firstname' value='John'/>"
3976 " <INPUT type='text' id='lastname' value='Smith'/>"
3977 " </FIELDSET>"
3978 " <FIELDSET>"
3979 " <LABEL for='email'>Email:</LABEL>"
3980 " <INPUT type='text' id='email' value='john@example.com'/>"
3981 " </FIELDSET>"
3982 "</DIV>");
3984 WebFrame* frame = GetMainFrame();
3985 ASSERT_NE(nullptr, frame);
3987 control_elements = GetUnownedAutofillableFormFieldElements(
3988 frame->document().all(), &fieldsets);
3989 ASSERT_EQ(3U, control_elements.size());
3990 ASSERT_EQ(2U, fieldsets.size());
3992 FormData form;
3993 EXPECT_TRUE(UnownedCheckoutFormElementsAndFieldSetsToFormData(
3994 fieldsets, control_elements, nullptr, frame->document(), extract_mask,
3995 &form, nullptr));
3997 EXPECT_TRUE(form.name.empty());
3998 EXPECT_EQ(frame->document().url(), form.origin);
3999 EXPECT_FALSE(form.action.is_valid());
4001 const std::vector<FormFieldData>& fields = form.fields;
4002 ASSERT_EQ(3U, fields.size());
4004 FormFieldData expected;
4005 expected.form_control_type = "text";
4006 expected.max_length = WebInputElement::defaultMaxLength();
4008 expected.name = ASCIIToUTF16("firstname");
4009 expected.value = ASCIIToUTF16("John");
4010 expected.label = ASCIIToUTF16("First name:");
4011 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
4013 expected.name = ASCIIToUTF16("lastname");
4014 expected.value = ASCIIToUTF16("Smith");
4015 expected.label = ASCIIToUTF16("Last name:");
4016 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
4018 expected.name = ASCIIToUTF16("email");
4019 expected.value = ASCIIToUTF16("john@example.com");
4020 expected.label = ASCIIToUTF16("Email:");
4021 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
4024 TEST_F(FormAutofillTest,
4025 UnownedFormElementsAndFieldSetsToFormDataControlOutsideOfFieldset) {
4026 std::vector<WebElement> fieldsets;
4027 std::vector<WebFormControlElement> control_elements;
4029 const ExtractMask extract_mask =
4030 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
4032 LoadHTML("<HEAD><TITLE>shipping details</TITLE></HEAD>"
4033 "<DIV>"
4034 " <FIELDSET>"
4035 " <LABEL for='firstname'>First name:</LABEL>"
4036 " <LABEL for='lastname'>Last name:</LABEL>"
4037 " <INPUT type='text' id='firstname' value='John'/>"
4038 " <INPUT type='text' id='lastname' value='Smith'/>"
4039 " <LABEL for='email'>Email:</LABEL>"
4040 " </FIELDSET>"
4041 " <INPUT type='text' id='email' value='john@example.com'/>"
4042 "</DIV>");
4044 WebFrame* frame = GetMainFrame();
4045 ASSERT_NE(nullptr, frame);
4047 control_elements = GetUnownedAutofillableFormFieldElements(
4048 frame->document().all(), &fieldsets);
4049 ASSERT_EQ(3U, control_elements.size());
4050 ASSERT_EQ(1U, fieldsets.size());
4052 FormData form;
4053 EXPECT_TRUE(UnownedCheckoutFormElementsAndFieldSetsToFormData(
4054 fieldsets, control_elements, nullptr, frame->document(), extract_mask,
4055 &form, nullptr));
4057 EXPECT_TRUE(form.name.empty());
4058 EXPECT_EQ(frame->document().url(), form.origin);
4059 EXPECT_FALSE(form.action.is_valid());
4061 const std::vector<FormFieldData>& fields = form.fields;
4062 ASSERT_EQ(3U, fields.size());
4064 FormFieldData expected;
4065 expected.form_control_type = "text";
4066 expected.max_length = WebInputElement::defaultMaxLength();
4068 expected.name = ASCIIToUTF16("firstname");
4069 expected.value = ASCIIToUTF16("John");
4070 expected.label = ASCIIToUTF16("First name:");
4071 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
4073 expected.name = ASCIIToUTF16("lastname");
4074 expected.value = ASCIIToUTF16("Smith");
4075 expected.label = ASCIIToUTF16("Last name:");
4076 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
4078 expected.name = ASCIIToUTF16("email");
4079 expected.value = ASCIIToUTF16("john@example.com");
4080 expected.label = ASCIIToUTF16("Email:");
4081 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
4084 TEST_F(FormAutofillTest, UnownedFormElementsAndFieldSetsToFormDataWithForm) {
4085 std::vector<WebElement> fieldsets;
4086 std::vector<WebFormControlElement> control_elements;
4088 const ExtractMask extract_mask =
4089 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
4091 LoadHTML(kFormHtml);
4093 WebFrame* frame = GetMainFrame();
4094 ASSERT_NE(nullptr, frame);
4096 control_elements = GetUnownedAutofillableFormFieldElements(
4097 frame->document().all(), &fieldsets);
4098 ASSERT_TRUE(control_elements.empty());
4099 ASSERT_TRUE(fieldsets.empty());
4101 FormData form;
4102 EXPECT_FALSE(UnownedCheckoutFormElementsAndFieldSetsToFormData(
4103 fieldsets, control_elements, nullptr, frame->document(), extract_mask,
4104 &form, nullptr));
4107 } // namespace autofill