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

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

Issue 11198048: [Autofill] Update the autocomplete types implementation to match the current HTML spec. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleaner code & tests Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/form_field_data.cc ('k') | chrome/renderer/autofill/form_autofill_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/string16.h" 8 #include "base/string16.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 157
158 WebElement web_element = frame->document().getElementById("element"); 158 WebElement web_element = frame->document().getElementById("element");
159 WebFormControlElement element = web_element.to<WebFormControlElement>(); 159 WebFormControlElement element = web_element.to<WebFormControlElement>();
160 FormFieldData result; 160 FormFieldData result;
161 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result); 161 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result);
162 162
163 FormFieldData expected; 163 FormFieldData expected;
164 expected.name = ASCIIToUTF16("element"); 164 expected.name = ASCIIToUTF16("element");
165 expected.value = ASCIIToUTF16("value"); 165 expected.value = ASCIIToUTF16("value");
166 expected.form_control_type = ASCIIToUTF16("text"); 166 expected.form_control_type = ASCIIToUTF16("text");
167 expected.autocomplete_attribute = ASCIIToUTF16("off");
167 expected.max_length = WebInputElement::defaultMaxLength(); 168 expected.max_length = WebInputElement::defaultMaxLength();
168 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); 169 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
169 } 170 }
170 171
171 // We should be able to extract a text field with maxlength specified. 172 // We should be able to extract a text field with maxlength specified.
172 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMaxLength) { 173 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMaxLength) {
173 LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\"" 174 LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\""
174 " maxlength=\"5\"/>"); 175 " maxlength=\"5\"/>");
175 176
176 WebFrame* frame = GetMainFrame(); 177 WebFrame* frame = GetMainFrame();
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result); 310 WebFormControlElementToFormField(element, autofill::EXTRACT_VALUE, &result);
310 expected.name = ASCIIToUTF16("submit"); 311 expected.name = ASCIIToUTF16("submit");
311 expected.form_control_type = ASCIIToUTF16("submit"); 312 expected.form_control_type = ASCIIToUTF16("submit");
312 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); 313 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
313 } 314 }
314 315
315 // We should be able to extract the autocompletetype attribute. 316 // We should be able to extract the autocompletetype attribute.
316 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompletetype) { 317 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompletetype) {
317 std::string html = 318 std::string html =
318 "<INPUT type=\"text\" id=\"absent\"/>" 319 "<INPUT type=\"text\" id=\"absent\"/>"
319 "<INPUT type=\"text\" id=\"empty\" x-autocompletetype=\"\"/>" 320 "<INPUT type=\"text\" id=\"empty\" autocomplete=\"\"/>"
320 "<INPUT type=\"text\" id=\"whitespace\" x-autocompletetype=\" \"/>" 321 "<INPUT type=\"text\" id=\"off\" autocomplete=\"off\"/>"
321 "<INPUT type=\"text\" id=\"regular\" x-autocompletetype=\"email\"/>" 322 "<INPUT type=\"text\" id=\"regular\" autocomplete=\"email\"/>"
322 "<INPUT type=\"text\" id=\"multi-valued\" " 323 "<INPUT type=\"text\" id=\"multi-valued\" "
323 " x-autocompletetype=\"x-confirm-email email\"/>" 324 " autocomplete=\"billing email\"/>"
324 "<INPUT type=\"text\" id=\"unprefixed\" autocompletetype=\"email\"/>" 325 "<INPUT type=\"text\" id=\"experimental\" x-autocompletetype=\"email\"/>"
325 "<SELECT id=\"select\" x-autocompletetype=\"state\"/>" 326 "<SELECT id=\"select\" autocomplete=\"state\"/>"
326 " <OPTION value=\"CA\">California</OPTION>" 327 " <OPTION value=\"CA\">California</OPTION>"
327 " <OPTION value=\"TX\">Texas</OPTION>" 328 " <OPTION value=\"TX\">Texas</OPTION>"
328 "</SELECT>"; 329 "</SELECT>";
329 html += 330 html +=
330 "<INPUT type=\"text\" id=\"malicious\" x-autocompletetype=\"" + 331 "<INPUT type=\"text\" id=\"malicious\" autocomplete=\"" +
331 std::string(10000, 'x') + "\"/>"; 332 std::string(10000, 'x') + "\"/>";
332 LoadHTML(html.c_str()); 333 LoadHTML(html.c_str());
333 334
334 WebFrame* frame = GetMainFrame(); 335 WebFrame* frame = GetMainFrame();
335 ASSERT_NE(static_cast<WebFrame*>(NULL), frame); 336 ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
336 337
337 // An absent attribute is equivalent to an empty one. 338 struct TestCase {
338 WebElement web_element = frame->document().getElementById("absent"); 339 const std::string element_id;
339 WebFormControlElement element = web_element.to<WebFormControlElement>(); 340 const std::string form_control_type;
340 FormFieldData result1; 341 const std::string autocomplete_attribute;
341 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result1); 342 };
343 TestCase test_cases[] = {
344 // An absent attribute is equivalent to an empty one.
345 { "absent", "text", "" },
346 // Make sure there are no issues parsing an empty attribute.
347 { "empty", "text", "" },
348 // Make sure there are no issues parsing an attribute value that isn't a
349 // type hint.
350 { "off", "text", "off" },
351 // Common case: exactly one type specified.
352 { "regular", "text", "email" },
353 // Verify that we correctly extract multiple tokens as well.
354 { "multi-valued", "text", "billing email" },
355 // We previously extracted this data from the experimental
356 // 'x-autocompletetype' attribute. Now that the field type hints are part
357 // of the spec under the autocomplete attribute, we no longer support the
358 // experimental version.
359 { "experimental", "text", "" },
360 // <select> elements should behave no differently from text fields here.
361 { "select", "select-one", "state" },
362 // Very long attribute values should be replaced by a default string, to
363 // prevent malicious websites from DOSing the browser process.
364 { "malicious", "text", "x-max-data-length-exceeded" },
365 };
Dan Beam 2012/10/19 04:25:41 this looks way better!
342 366
343 FormFieldData expected; 367 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
344 expected.name = ASCIIToUTF16("absent"); 368 WebElement web_element = frame->document().getElementById(
345 expected.form_control_type = ASCIIToUTF16("text"); 369 ASCIIToUTF16(test_cases[i].element_id));
346 expected.autocomplete_type = string16(); 370 WebFormControlElement element = web_element.to<WebFormControlElement>();
347 expected.max_length = WebInputElement::defaultMaxLength(); 371 FormFieldData result;
348 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result1); 372 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result);
349 373
350 web_element = frame->document().getElementById("empty"); 374 FormFieldData expected;
351 element = web_element.to<WebFormControlElement>(); 375 expected.name = ASCIIToUTF16(test_cases[i].element_id);
352 FormFieldData result2; 376 expected.form_control_type = ASCIIToUTF16(test_cases[i].form_control_type);
353 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result2); 377 expected.autocomplete_attribute =
354 expected.name = ASCIIToUTF16("empty"); 378 ASCIIToUTF16(test_cases[i].autocomplete_attribute);
355 expected.form_control_type = ASCIIToUTF16("text"); 379 if (test_cases[i].form_control_type == "text")
356 expected.autocomplete_type = string16(); 380 expected.max_length = WebInputElement::defaultMaxLength();
Dan Beam 2012/10/19 04:25:41 nit: ternary IMO, if it doesn't look gross
Ilya Sherman 2012/10/19 04:54:11 Using a ternary operator results in wrapped lines
357 expected.max_length = WebInputElement::defaultMaxLength(); 381 else
358 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result2); 382 expected.max_length = 0;
359 383
360 // The renderer should trim whitespace. 384 SCOPED_TRACE(test_cases[i].element_id);
361 web_element = frame->document().getElementById("whitespace"); 385 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
362 element = web_element.to<WebFormControlElement>(); 386 }
363 FormFieldData result3;
364 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result3);
365 expected.name = ASCIIToUTF16("whitespace");
366 expected.form_control_type = ASCIIToUTF16("text");
367 expected.autocomplete_type = string16();
368 expected.max_length = WebInputElement::defaultMaxLength();
369 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result3);
370
371 // Common case: exactly one type specified.
372 web_element = frame->document().getElementById("regular");
373 element = web_element.to<WebFormControlElement>();
374 FormFieldData result4;
375 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result4);
376 expected.name = ASCIIToUTF16("regular");
377 expected.form_control_type = ASCIIToUTF16("text");
378 expected.autocomplete_type = ASCIIToUTF16("email");
379 expected.max_length = WebInputElement::defaultMaxLength();
380 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result4);
381
382 // Verify that we correctly extract fallback types as well.
383 web_element = frame->document().getElementById("multi-valued");
384 element = web_element.to<WebFormControlElement>();
385 FormFieldData result5;
386 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result5);
387 expected.name = ASCIIToUTF16("multi-valued");
388 expected.form_control_type = ASCIIToUTF16("text");
389 expected.autocomplete_type = ASCIIToUTF16("x-confirm-email email");
390 expected.max_length = WebInputElement::defaultMaxLength();
391 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result5);
392
393 // The attribute is not yet part of the HTML standard, so we only recognize
394 // the prefixed version -- 'x-autocompletetype' -- and not the unprefixed one.
395 web_element = frame->document().getElementById("unprefixed");
396 element = web_element.to<WebFormControlElement>();
397 FormFieldData result6;
398 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result6);
399 expected.name = ASCIIToUTF16("unprefixed");
400 expected.form_control_type = ASCIIToUTF16("text");
401 expected.autocomplete_type = string16();
402 expected.max_length = WebInputElement::defaultMaxLength();
403 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result6);
404
405 // <select> elements should behave no differently from text fields here.
406 web_element = frame->document().getElementById("select");
407 element = web_element.to<WebFormControlElement>();
408 FormFieldData result7;
409 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result7);
410 expected.name = ASCIIToUTF16("select");
411 expected.form_control_type = ASCIIToUTF16("select-one");
412 expected.autocomplete_type = ASCIIToUTF16("state");
413 expected.max_length = 0;
414 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result7);
415
416 // Very long attribute values should be replaced by a default string, to
417 // prevent malicious websites from DOSing the browser process.
418 web_element = frame->document().getElementById("malicious");
419 element = web_element.to<WebFormControlElement>();
420 FormFieldData result8;
421 WebFormControlElementToFormField(element, autofill::EXTRACT_NONE, &result8);
422 expected.name = ASCIIToUTF16("malicious");
423 expected.form_control_type = ASCIIToUTF16("text");
424 expected.autocomplete_type = ASCIIToUTF16("x-max-data-length-exceeded");
425 expected.max_length = WebInputElement::defaultMaxLength();
426 EXPECT_FORM_FIELD_DATA_EQUALS(expected, result8);
427 } 387 }
428 388
429 TEST_F(FormAutofillTest, WebFormElementToFormData) { 389 TEST_F(FormAutofillTest, WebFormElementToFormData) {
430 LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" 390 LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
431 " <LABEL for=\"firstname\">First name:</LABEL>" 391 " <LABEL for=\"firstname\">First name:</LABEL>"
432 " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>" 392 " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
433 " <LABEL for=\"lastname\">Last name:</LABEL>" 393 " <LABEL for=\"lastname\">Last name:</LABEL>"
434 " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>" 394 " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
435 " <LABEL for=\"state\">State:</LABEL>" 395 " <LABEL for=\"state\">State:</LABEL>"
436 " <SELECT id=\"state\"/>" 396 " <SELECT id=\"state\"/>"
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 expected.value = ASCIIToUTF16("John"); 699 expected.value = ASCIIToUTF16("John");
740 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); 700 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
741 EXPECT_FORM_FIELD_DATA_EQUALS(expected, field); 701 EXPECT_FORM_FIELD_DATA_EQUALS(expected, field);
742 702
743 expected.name = ASCIIToUTF16("lastname"); 703 expected.name = ASCIIToUTF16("lastname");
744 expected.value = ASCIIToUTF16("Smith"); 704 expected.value = ASCIIToUTF16("Smith");
745 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); 705 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
746 706
747 expected.name = ASCIIToUTF16("email"); 707 expected.name = ASCIIToUTF16("email");
748 expected.value = ASCIIToUTF16("john@example.com"); 708 expected.value = ASCIIToUTF16("john@example.com");
709 expected.autocomplete_attribute = ASCIIToUTF16("off");
749 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); 710 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
750 711
751 expected.name = ASCIIToUTF16("phone"); 712 expected.name = ASCIIToUTF16("phone");
752 expected.value = ASCIIToUTF16("1.800.555.1234"); 713 expected.value = ASCIIToUTF16("1.800.555.1234");
714 expected.autocomplete_attribute = string16();
753 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); 715 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]);
754 716
755 // Try again, but require autocomplete. 717 // Try again, but require autocomplete.
756 FormData form2; 718 FormData form2;
757 FormFieldData field2; 719 FormFieldData field2;
758 EXPECT_TRUE(FindFormAndFieldForInputElement(input_element, &form2, &field2, 720 EXPECT_TRUE(FindFormAndFieldForInputElement(input_element, &form2, &field2,
759 autofill::REQUIRE_AUTOCOMPLETE)); 721 autofill::REQUIRE_AUTOCOMPLETE));
760 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name); 722 EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
761 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin); 723 EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
762 EXPECT_EQ(GURL("http://buh.com"), form2.action); 724 EXPECT_EQ(GURL("http://buh.com"), form2.action);
(...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after
2489 expected.name = ASCIIToUTF16("firstname"); 2451 expected.name = ASCIIToUTF16("firstname");
2490 expected.value = string16(); 2452 expected.value = string16();
2491 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); 2453 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
2492 2454
2493 expected.name = ASCIIToUTF16("lastname"); 2455 expected.name = ASCIIToUTF16("lastname");
2494 expected.value = string16(); 2456 expected.value = string16();
2495 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); 2457 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
2496 2458
2497 expected.name = ASCIIToUTF16("noAC"); 2459 expected.name = ASCIIToUTF16("noAC");
2498 expected.value = string16(); 2460 expected.value = string16();
2461 expected.autocomplete_attribute = ASCIIToUTF16("off");
2499 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); 2462 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
2500 2463
2501 expected.name = ASCIIToUTF16("notenabled"); 2464 expected.name = ASCIIToUTF16("notenabled");
2502 expected.value = ASCIIToUTF16("no clear"); 2465 expected.value = ASCIIToUTF16("no clear");
2466 expected.autocomplete_attribute = string16();
2503 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]); 2467 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]);
2504 2468
2505 // Verify that the cursor position has been updated. 2469 // Verify that the cursor position has been updated.
2506 EXPECT_EQ(0, firstname.selectionStart()); 2470 EXPECT_EQ(0, firstname.selectionStart());
2507 EXPECT_EQ(0, firstname.selectionEnd()); 2471 EXPECT_EQ(0, firstname.selectionEnd());
2508 } 2472 }
2509 2473
2510 TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOne) { 2474 TEST_F(FormAutofillTest, ClearFormWithNodeContainingSelectOne) {
2511 LoadHTML( 2475 LoadHTML(
2512 "<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">" 2476 "<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 expected.form_control_type = ASCIIToUTF16("text"); 2895 expected.form_control_type = ASCIIToUTF16("text");
2932 expected.max_length = WebInputElement::defaultMaxLength(); 2896 expected.max_length = WebInputElement::defaultMaxLength();
2933 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); 2897 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]);
2934 2898
2935 expected.name = ASCIIToUTF16("country"); 2899 expected.name = ASCIIToUTF16("country");
2936 expected.value = ASCIIToUTF16("AL"); 2900 expected.value = ASCIIToUTF16("AL");
2937 expected.form_control_type = ASCIIToUTF16("select-one"); 2901 expected.form_control_type = ASCIIToUTF16("select-one");
2938 expected.max_length = 0; 2902 expected.max_length = 0;
2939 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); 2903 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
2940 } 2904 }
OLDNEW
« no previous file with comments | « chrome/common/form_field_data.cc ('k') | chrome/renderer/autofill/form_autofill_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698