Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/strings/string16.h" | 8 #include "base/strings/string16.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 " </SELECT>" | 94 " </SELECT>" |
| 95 " <SELECT id='select-unchanged'>" | 95 " <SELECT id='select-unchanged'>" |
| 96 " <OPTION value='CA' selected>California</OPTION>" | 96 " <OPTION value='CA' selected>California</OPTION>" |
| 97 " <OPTION value='TX'>Texas</OPTION>" | 97 " <OPTION value='TX'>Texas</OPTION>" |
| 98 " </SELECT>" | 98 " </SELECT>" |
| 99 " <TEXTAREA id='textarea'></TEXTAREA>" | 99 " <TEXTAREA id='textarea'></TEXTAREA>" |
| 100 " <TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" | 100 " <TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" |
| 101 " <INPUT type='submit' name='reply-send' value='Send'/>" | 101 " <INPUT type='submit' name='reply-send' value='Send'/>" |
| 102 "</FORM>"; | 102 "</FORM>"; |
| 103 | 103 |
| 104 // This constant uses a mixed-case title tag to be sure that the title match is | |
| 105 // not case-sensitive. Other tests in this file use an all-lower title tag. | |
| 104 const char kUnownedFormHtml[] = | 106 const char kUnownedFormHtml[] = |
| 105 "<HEAD><TITLE>enter shipping info</TITLE></HEAD>" | 107 "<HEAD><TITLE>Enter Shipping Info</TITLE></HEAD>" |
| 106 "<INPUT type='text' id='firstname'/>" | 108 "<INPUT type='text' id='firstname'/>" |
| 107 "<INPUT type='text' id='lastname'/>" | 109 "<INPUT type='text' id='lastname'/>" |
| 108 "<INPUT type='hidden' id='imhidden'/>" | 110 "<INPUT type='hidden' id='imhidden'/>" |
| 109 "<INPUT type='text' id='notempty' value='Hi'/>" | 111 "<INPUT type='text' id='notempty' value='Hi'/>" |
| 110 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" | 112 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" |
| 111 "<INPUT type='text' disabled='disabled' id='notenabled'/>" | 113 "<INPUT type='text' disabled='disabled' id='notenabled'/>" |
| 112 "<INPUT type='text' readonly id='readonly'/>" | 114 "<INPUT type='text' readonly id='readonly'/>" |
| 113 "<INPUT type='text' style='visibility: hidden'" | 115 "<INPUT type='text' style='visibility: hidden'" |
| 114 " id='invisible'/>" | 116 " id='invisible'/>" |
| 115 "<INPUT type='text' style='display: none' id='displaynone'/>" | 117 "<INPUT type='text' style='display: none' id='displaynone'/>" |
| 116 "<INPUT type='month' id='month'/>" | 118 "<INPUT type='month' id='month'/>" |
| 117 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" | 119 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" |
| 118 "<SELECT id='select'>" | 120 "<SELECT id='select'>" |
| 119 " <OPTION></OPTION>" | 121 " <OPTION></OPTION>" |
| 120 " <OPTION value='CA'>California</OPTION>" | 122 " <OPTION value='CA'>California</OPTION>" |
| 121 " <OPTION value='TX'>Texas</OPTION>" | 123 " <OPTION value='TX'>Texas</OPTION>" |
| 122 "</SELECT>" | 124 "</SELECT>" |
| 123 "<SELECT id='select-nonempty'>" | 125 "<SELECT id='select-nonempty'>" |
| 124 " <OPTION value='CA' selected>California</OPTION>" | 126 " <OPTION value='CA' selected>California</OPTION>" |
| 125 " <OPTION value='TX'>Texas</OPTION>" | 127 " <OPTION value='TX'>Texas</OPTION>" |
| 126 "</SELECT>" | 128 "</SELECT>" |
| 127 "<SELECT id='select-unchanged'>" | 129 "<SELECT id='select-unchanged'>" |
| 128 " <OPTION value='CA' selected>California</OPTION>" | 130 " <OPTION value='CA' selected>California</OPTION>" |
| 129 " <OPTION value='TX'>Texas</OPTION>" | 131 " <OPTION value='TX'>Texas</OPTION>" |
| 130 "</SELECT>" | 132 "</SELECT>" |
| 131 "<TEXTAREA id='textarea'></TEXTAREA>" | 133 "<TEXTAREA id='textarea'></TEXTAREA>" |
| 132 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" | 134 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" |
| 133 "<INPUT type='submit' name='reply-send' value='Send'/>"; | 135 "<INPUT type='submit' name='reply-send' value='Send'/>"; |
| 134 | 136 |
| 137 // This constant has no title tag, and should be passed to | |
| 138 // LoadHTMLWithURLOverride to test the detection of unowned forms by URL. | |
| 139 const char kUnownedUntitledFormHtml[] = | |
| 140 "<INPUT type='text' id='firstname'/>" | |
| 141 "<INPUT type='text' id='lastname'/>" | |
| 142 "<INPUT type='hidden' id='imhidden'/>" | |
| 143 "<INPUT type='text' id='notempty' value='Hi'/>" | |
| 144 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" | |
| 145 "<INPUT type='text' disabled='disabled' id='notenabled'/>" | |
| 146 "<INPUT type='text' readonly id='readonly'/>" | |
| 147 "<INPUT type='text' style='visibility: hidden'" | |
| 148 " id='invisible'/>" | |
| 149 "<INPUT type='text' style='display: none' id='displaynone'/>" | |
| 150 "<INPUT type='month' id='month'/>" | |
| 151 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" | |
| 152 "<SELECT id='select'>" | |
| 153 " <OPTION></OPTION>" | |
| 154 " <OPTION value='CA'>California</OPTION>" | |
| 155 " <OPTION value='TX'>Texas</OPTION>" | |
| 156 "</SELECT>" | |
| 157 "<SELECT id='select-nonempty'>" | |
| 158 " <OPTION value='CA' selected>California</OPTION>" | |
| 159 " <OPTION value='TX'>Texas</OPTION>" | |
| 160 "</SELECT>" | |
| 161 "<SELECT id='select-unchanged'>" | |
| 162 " <OPTION value='CA' selected>California</OPTION>" | |
| 163 " <OPTION value='TX'>Texas</OPTION>" | |
| 164 "</SELECT>" | |
| 165 "<TEXTAREA id='textarea'></TEXTAREA>" | |
| 166 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" | |
| 167 "<INPUT type='submit' name='reply-send' value='Send'/>"; | |
| 168 | |
| 169 // This constant does not have a title tag, but should match an unowned form | |
| 170 // anyway because it is not English. | |
| 171 const char kUnownedNonEnglishFormHtml[] = | |
| 172 "<HTML LANG='fr'>" | |
| 173 "<INPUT type='text' id='firstname'/>" | |
| 174 "<INPUT type='text' id='lastname'/>" | |
| 175 "<INPUT type='hidden' id='imhidden'/>" | |
| 176 "<INPUT type='text' id='notempty' value='Hi'/>" | |
| 177 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" | |
| 178 "<INPUT type='text' disabled='disabled' id='notenabled'/>" | |
| 179 "<INPUT type='text' readonly id='readonly'/>" | |
| 180 "<INPUT type='text' style='visibility: hidden'" | |
| 181 " id='invisible'/>" | |
| 182 "<INPUT type='text' style='display: none' id='displaynone'/>" | |
| 183 "<INPUT type='month' id='month'/>" | |
| 184 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" | |
| 185 "<SELECT id='select'>" | |
| 186 " <OPTION></OPTION>" | |
| 187 " <OPTION value='CA'>California</OPTION>" | |
| 188 " <OPTION value='TX'>Texas</OPTION>" | |
| 189 "</SELECT>" | |
| 190 "<SELECT id='select-nonempty'>" | |
| 191 " <OPTION value='CA' selected>California</OPTION>" | |
| 192 " <OPTION value='TX'>Texas</OPTION>" | |
| 193 "</SELECT>" | |
| 194 "<SELECT id='select-unchanged'>" | |
| 195 " <OPTION value='CA' selected>California</OPTION>" | |
| 196 " <OPTION value='TX'>Texas</OPTION>" | |
| 197 "</SELECT>" | |
| 198 "<TEXTAREA id='textarea'></TEXTAREA>" | |
| 199 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" | |
| 200 "<INPUT type='submit' name='reply-send' value='Send'/>" | |
| 201 "</HTML>"; | |
| 202 | |
| 135 std::string RetrievalMethodToString( | 203 std::string RetrievalMethodToString( |
| 136 const WebElementDescriptor::RetrievalMethod& method) { | 204 const WebElementDescriptor::RetrievalMethod& method) { |
| 137 switch (method) { | 205 switch (method) { |
| 138 case WebElementDescriptor::CSS_SELECTOR: | 206 case WebElementDescriptor::CSS_SELECTOR: |
| 139 return "CSS_SELECTOR"; | 207 return "CSS_SELECTOR"; |
| 140 case WebElementDescriptor::ID: | 208 case WebElementDescriptor::ID: |
| 141 return "ID"; | 209 return "ID"; |
| 142 case WebElementDescriptor::NONE: | 210 case WebElementDescriptor::NONE: |
| 143 return "NONE"; | 211 return "NONE"; |
| 144 } | 212 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 } | 320 } |
| 253 | 321 |
| 254 typedef void (*FillFormFunction)(const FormData& form, | 322 typedef void (*FillFormFunction)(const FormData& form, |
| 255 const WebFormControlElement& element); | 323 const WebFormControlElement& element); |
| 256 | 324 |
| 257 typedef WebString (*GetValueFunction)(WebFormControlElement element); | 325 typedef WebString (*GetValueFunction)(WebFormControlElement element); |
| 258 | 326 |
| 259 // Test FormFillxxx functions. | 327 // Test FormFillxxx functions. |
| 260 void TestFormFillFunctions(const char* html, | 328 void TestFormFillFunctions(const char* html, |
| 261 bool unowned, | 329 bool unowned, |
| 330 const char* url_override, | |
| 262 const AutofillFieldCase* field_cases, | 331 const AutofillFieldCase* field_cases, |
| 263 size_t number_of_field_cases, | 332 size_t number_of_field_cases, |
| 264 FillFormFunction fill_form_function, | 333 FillFormFunction fill_form_function, |
| 265 GetValueFunction get_value_function) { | 334 GetValueFunction get_value_function) { |
| 266 LoadHTML(html); | 335 if (url_override) |
| 336 LoadHTMLWithUrlOverride(html, url_override); | |
| 337 else | |
| 338 LoadHTML(html); | |
| 267 | 339 |
| 268 WebFrame* web_frame = GetMainFrame(); | 340 WebFrame* web_frame = GetMainFrame(); |
| 269 ASSERT_NE(nullptr, web_frame); | 341 ASSERT_NE(nullptr, web_frame); |
| 270 | 342 |
| 271 FormCache form_cache(*web_frame); | 343 FormCache form_cache(*web_frame); |
| 272 std::vector<FormData> forms = form_cache.ExtractNewForms(); | 344 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 273 ASSERT_EQ(1U, forms.size()); | 345 ASSERT_EQ(1U, forms.size()); |
| 274 | 346 |
| 275 // Get the input element we want to find. | 347 // Get the input element we want to find. |
| 276 WebInputElement input_element = GetInputElementById("firstname"); | 348 WebInputElement input_element = GetInputElementById("firstname"); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 291 FormFieldData expected; | 363 FormFieldData expected; |
| 292 // Verify field's initial value. | 364 // Verify field's initial value. |
| 293 for (size_t i = 0; i < number_of_field_cases; ++i) { | 365 for (size_t i = 0; i < number_of_field_cases; ++i) { |
| 294 SCOPED_TRACE(base::StringPrintf("Verify initial value for field %s", | 366 SCOPED_TRACE(base::StringPrintf("Verify initial value for field %s", |
| 295 field_cases[i].name)); | 367 field_cases[i].name)); |
| 296 expected.form_control_type = field_cases[i].form_control_type; | 368 expected.form_control_type = field_cases[i].form_control_type; |
| 297 expected.max_length = | 369 expected.max_length = |
| 298 expected.form_control_type == "text" ? | 370 expected.form_control_type == "text" ? |
| 299 WebInputElement::defaultMaxLength() : 0; | 371 WebInputElement::defaultMaxLength() : 0; |
| 300 expected.name = ASCIIToUTF16(field_cases[i].name); | 372 expected.name = ASCIIToUTF16(field_cases[i].name); |
| 301 expected.value = ASCIIToUTF16(field_cases[i].initial_value); | 373 expected.value = ASCIIToUTF16(field_cases[i].initial_value); |
|
jungshik at Google
2015/12/16 21:14:04
It's not in this CL, but why is ASCIIToUTF16 used
| |
| 302 expected.autocomplete_attribute = field_cases[i].autocomplete_attribute; | 374 expected.autocomplete_attribute = field_cases[i].autocomplete_attribute; |
| 303 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[i]); | 375 EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[i]); |
| 304 // Fill the form_data for the field. | 376 // Fill the form_data for the field. |
| 305 form_data.fields[i].value = ASCIIToUTF16(field_cases[i].autofill_value); | 377 form_data.fields[i].value = ASCIIToUTF16(field_cases[i].autofill_value); |
|
jungshik at Google
2015/12/16 21:14:04
ditto here and elsewhere (where the input to ASCII
Evan Stade
2015/12/16 22:21:35
I assume it's because this is a test file and all
| |
| 306 // Set the is_autofilled property for the field. | 378 // Set the is_autofilled property for the field. |
| 307 form_data.fields[i].is_autofilled = field_cases[i].should_be_autofilled; | 379 form_data.fields[i].is_autofilled = field_cases[i].should_be_autofilled; |
| 308 } | 380 } |
| 309 | 381 |
| 310 // Autofill the form using the given fill form function. | 382 // Autofill the form using the given fill form function. |
| 311 fill_form_function(form_data, input_element); | 383 fill_form_function(form_data, input_element); |
| 312 | 384 |
| 313 // Validate Autofill or Preview results. | 385 // Validate Autofill or Preview results. |
| 314 for (size_t i = 0; i < number_of_field_cases; ++i) { | 386 for (size_t i = 0; i < number_of_field_cases; ++i) { |
| 315 ValidateFilledField(field_cases[i], get_value_function); | 387 ValidateFilledField(field_cases[i], get_value_function); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 345 WebFormControlElement GetFormControlElementById(const WebString& id) { | 417 WebFormControlElement GetFormControlElementById(const WebString& id) { |
| 346 return GetMainFrame()->document().getElementById( | 418 return GetMainFrame()->document().getElementById( |
| 347 id).to<WebFormControlElement>(); | 419 id).to<WebFormControlElement>(); |
| 348 } | 420 } |
| 349 | 421 |
| 350 WebInputElement GetInputElementById(const WebString& id) { | 422 WebInputElement GetInputElementById(const WebString& id) { |
| 351 return GetMainFrame()->document().getElementById( | 423 return GetMainFrame()->document().getElementById( |
| 352 id).to<WebInputElement>(); | 424 id).to<WebInputElement>(); |
| 353 } | 425 } |
| 354 | 426 |
| 355 void TestFillForm(const char* html, bool unowned) { | 427 void TestFillForm(const char* html, bool unowned, const char* url_override) { |
| 356 static const AutofillFieldCase field_cases[] = { | 428 static const AutofillFieldCase field_cases[] = { |
| 357 // fields: form_control_type, name, initial_value, autocomplete_attribute, | 429 // fields: form_control_type, name, initial_value, autocomplete_attribute, |
| 358 // should_be_autofilled, autofill_value, expected_value | 430 // should_be_autofilled, autofill_value, expected_value |
| 359 | 431 |
| 360 // Regular empty fields (firstname & lastname) should be autofilled. | 432 // Regular empty fields (firstname & lastname) should be autofilled. |
| 361 {"text", | 433 {"text", |
| 362 "firstname", | 434 "firstname", |
| 363 "", | 435 "", |
| 364 "", | 436 "", |
| 365 true, | 437 true, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 406 "some multi-\nline value"}, | 478 "some multi-\nline value"}, |
| 407 // Non-empty textarea elements should not be autofilled. | 479 // Non-empty textarea elements should not be autofilled. |
| 408 {"textarea", | 480 {"textarea", |
| 409 "textarea-nonempty", | 481 "textarea-nonempty", |
| 410 "Go\naway!", | 482 "Go\naway!", |
| 411 "", | 483 "", |
| 412 false, | 484 false, |
| 413 "some multi-\nline value", | 485 "some multi-\nline value", |
| 414 "Go\naway!"}, | 486 "Go\naway!"}, |
| 415 }; | 487 }; |
| 416 TestFormFillFunctions(html, unowned, field_cases, arraysize(field_cases), | 488 TestFormFillFunctions(html, unowned, url_override, |
| 489 field_cases, arraysize(field_cases), | |
| 417 FillForm, &GetValueWrapper); | 490 FillForm, &GetValueWrapper); |
| 418 // Verify preview selection. | 491 // Verify preview selection. |
| 419 WebInputElement firstname = GetInputElementById("firstname"); | 492 WebInputElement firstname = GetInputElementById("firstname"); |
| 420 EXPECT_EQ(16, firstname.selectionStart()); | 493 EXPECT_EQ(16, firstname.selectionStart()); |
| 421 EXPECT_EQ(16, firstname.selectionEnd()); | 494 EXPECT_EQ(16, firstname.selectionEnd()); |
| 422 } | 495 } |
| 423 | 496 |
| 424 void TestPreviewForm(const char* html, bool unowned) { | 497 void TestPreviewForm(const char* html, bool unowned, |
| 498 const char* url_override) { | |
| 425 static const AutofillFieldCase field_cases[] = { | 499 static const AutofillFieldCase field_cases[] = { |
| 426 // Normal empty fields should be previewed. | 500 // Normal empty fields should be previewed. |
| 427 {"text", | 501 {"text", |
| 428 "firstname", | 502 "firstname", |
| 429 "", | 503 "", |
| 430 "", | 504 "", |
| 431 true, | 505 true, |
| 432 "suggested firstname", | 506 "suggested firstname", |
| 433 "suggested firstname"}, | 507 "suggested firstname"}, |
| 434 {"text", | 508 {"text", |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 "suggested multi-\nline value"}, | 552 "suggested multi-\nline value"}, |
| 479 // Nonempty textarea elements should not be previewed. | 553 // Nonempty textarea elements should not be previewed. |
| 480 {"textarea", | 554 {"textarea", |
| 481 "textarea-nonempty", | 555 "textarea-nonempty", |
| 482 "Go\naway!", | 556 "Go\naway!", |
| 483 "", | 557 "", |
| 484 false, | 558 false, |
| 485 "suggested multi-\nline value", | 559 "suggested multi-\nline value", |
| 486 ""}, | 560 ""}, |
| 487 }; | 561 }; |
| 488 TestFormFillFunctions(html, unowned, field_cases, arraysize(field_cases), | 562 TestFormFillFunctions(html, unowned, url_override, |
| 563 field_cases, arraysize(field_cases), | |
| 489 &PreviewForm, &GetSuggestedValueWrapper); | 564 &PreviewForm, &GetSuggestedValueWrapper); |
| 490 | 565 |
| 491 // Verify preview selection. | 566 // Verify preview selection. |
| 492 WebInputElement firstname = GetInputElementById("firstname"); | 567 WebInputElement firstname = GetInputElementById("firstname"); |
| 493 EXPECT_EQ(0, firstname.selectionStart()); | 568 EXPECT_EQ(0, firstname.selectionStart()); |
| 494 EXPECT_EQ(19, firstname.selectionEnd()); | 569 EXPECT_EQ(19, firstname.selectionEnd()); |
| 495 } | 570 } |
| 496 | 571 |
| 572 void TestUnmatchedUnownedForm(const char* html, const char* url_override) { | |
| 573 if (url_override) | |
| 574 LoadHTMLWithUrlOverride(html, url_override); | |
| 575 else | |
| 576 LoadHTML(html); | |
| 577 | |
| 578 WebFrame* web_frame = GetMainFrame(); | |
| 579 ASSERT_NE(nullptr, web_frame); | |
| 580 | |
| 581 FormCache form_cache(*web_frame); | |
| 582 std::vector<FormData> forms = form_cache.ExtractNewForms(); | |
| 583 ASSERT_EQ(0U, forms.size()); | |
| 584 } | |
| 585 | |
| 497 void TestFindFormForInputElement(const char* html, bool unowned) { | 586 void TestFindFormForInputElement(const char* html, bool unowned) { |
| 498 LoadHTML(html); | 587 LoadHTML(html); |
| 499 WebFrame* web_frame = GetMainFrame(); | 588 WebFrame* web_frame = GetMainFrame(); |
| 500 ASSERT_NE(nullptr, web_frame); | 589 ASSERT_NE(nullptr, web_frame); |
| 501 | 590 |
| 502 FormCache form_cache(*web_frame); | 591 FormCache form_cache(*web_frame); |
| 503 std::vector<FormData> forms = form_cache.ExtractNewForms(); | 592 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 504 ASSERT_EQ(1U, forms.size()); | 593 ASSERT_EQ(1U, forms.size()); |
| 505 | 594 |
| 506 // Get the input element we want to find. | 595 // Get the input element we want to find. |
| (...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2449 "<TEXTAREA id='street-address'>" | 2538 "<TEXTAREA id='street-address'>" |
| 2450 "123 Fantasy Ln. " | 2539 "123 Fantasy Ln. " |
| 2451 "Apt. 42" | 2540 "Apt. 42" |
| 2452 "</TEXTAREA>" | 2541 "</TEXTAREA>" |
| 2453 "<INPUT type='submit' name='reply-send' value='Send'/>", | 2542 "<INPUT type='submit' name='reply-send' value='Send'/>", |
| 2454 true); | 2543 true); |
| 2455 } | 2544 } |
| 2456 | 2545 |
| 2457 // Test regular FillForm function. | 2546 // Test regular FillForm function. |
| 2458 TEST_F(FormAutofillTest, FillForm) { | 2547 TEST_F(FormAutofillTest, FillForm) { |
| 2459 TestFillForm(kFormHtml, false); | 2548 TestFillForm(kFormHtml, false, nullptr); |
| 2460 } | 2549 } |
| 2461 | 2550 |
| 2462 TEST_F(FormAutofillTest, FillFormForUnownedForm) { | 2551 TEST_F(FormAutofillTest, FillFormForUnownedForm) { |
| 2463 TestFillForm(kUnownedFormHtml, true); | 2552 TestFillForm(kUnownedFormHtml, true, nullptr); |
| 2553 } | |
| 2554 | |
| 2555 TEST_F(FormAutofillTest, FillFormForUnownedUntitledForm) { | |
| 2556 TestFillForm(kUnownedUntitledFormHtml, true, | |
| 2557 "http://example.test/checkout_flow"); | |
| 2558 } | |
| 2559 | |
| 2560 TEST_F(FormAutofillTest, FillFormForUnownedNonEnglishForm) { | |
| 2561 TestFillForm(kUnownedNonEnglishFormHtml, true, nullptr); | |
| 2562 } | |
| 2563 | |
| 2564 TEST_F(FormAutofillTest, FillFormForUnownedNonASCIIForm) { | |
| 2565 std::string html("<HEAD><TITLE>accented latin: \xC3\xA0, thai: \xE0\xB8\x81, " | |
| 2566 "control: \x04, nbsp: \xEF\xBB\xBF, non-BMP: \xF0\x9F\x8C\x80; This " | |
| 2567 "should match a CHECKOUT flow despite the non-ASCII chars" | |
| 2568 "</TITLE></HEAD>"); | |
| 2569 html.append(kUnownedUntitledFormHtml); | |
| 2570 TestFillForm(html.c_str(), true, nullptr); | |
| 2464 } | 2571 } |
| 2465 | 2572 |
| 2466 TEST_F(FormAutofillTest, FillFormIncludingNonFocusableElements) { | 2573 TEST_F(FormAutofillTest, FillFormIncludingNonFocusableElements) { |
| 2467 static const AutofillFieldCase field_cases[] = { | 2574 static const AutofillFieldCase field_cases[] = { |
| 2468 // fields: form_control_type, name, initial_value, autocomplete_attribute, | 2575 // fields: form_control_type, name, initial_value, autocomplete_attribute, |
| 2469 // should_be_autofilled, autofill_value, expected_value | 2576 // should_be_autofilled, autofill_value, expected_value |
| 2470 | 2577 |
| 2471 // Regular empty fields (firstname & lastname) should be autofilled. | 2578 // Regular empty fields (firstname & lastname) should be autofilled. |
| 2472 {"text", | 2579 {"text", |
| 2473 "firstname", | 2580 "firstname", |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2535 "some multi-\nline value"}, | 2642 "some multi-\nline value"}, |
| 2536 // Nonempty textarea elements should be overridden. | 2643 // Nonempty textarea elements should be overridden. |
| 2537 {"textarea", | 2644 {"textarea", |
| 2538 "textarea-nonempty", | 2645 "textarea-nonempty", |
| 2539 "Go\naway!", | 2646 "Go\naway!", |
| 2540 "", | 2647 "", |
| 2541 true, | 2648 true, |
| 2542 "some multi-\nline value", | 2649 "some multi-\nline value", |
| 2543 "some multi-\nline value"}, | 2650 "some multi-\nline value"}, |
| 2544 }; | 2651 }; |
| 2545 TestFormFillFunctions(kFormHtml, false, field_cases, arraysize(field_cases), | 2652 TestFormFillFunctions(kFormHtml, false, nullptr, |
| 2653 field_cases, arraysize(field_cases), | |
| 2546 &FillFormIncludingNonFocusableElementsWrapper, | 2654 &FillFormIncludingNonFocusableElementsWrapper, |
| 2547 &GetValueWrapper); | 2655 &GetValueWrapper); |
| 2548 } | 2656 } |
| 2549 | 2657 |
| 2550 TEST_F(FormAutofillTest, PreviewForm) { | 2658 TEST_F(FormAutofillTest, PreviewForm) { |
| 2551 TestPreviewForm(kFormHtml, false); | 2659 TestPreviewForm(kFormHtml, false, nullptr); |
| 2552 } | 2660 } |
| 2553 | 2661 |
| 2554 TEST_F(FormAutofillTest, PreviewFormForUnownedForm) { | 2662 TEST_F(FormAutofillTest, PreviewFormForUnownedForm) { |
| 2555 TestPreviewForm(kUnownedFormHtml, true); | 2663 TestPreviewForm(kUnownedFormHtml, true, nullptr); |
| 2556 } | 2664 } |
| 2557 | 2665 |
| 2666 TEST_F(FormAutofillTest, PreviewFormForUnownedUntitledForm) { | |
| 2667 // This test uses a mixed-case URL to be sure that the url match is not | |
| 2668 // case-sensitive. | |
| 2669 TestPreviewForm(kUnownedUntitledFormHtml, true, | |
| 2670 "http://example.test/Enter_Shipping_Address/"); | |
| 2671 } | |
| 2672 | |
| 2673 TEST_F(FormAutofillTest, PreviewFormForUnownedNonEnglishForm) { | |
| 2674 TestPreviewForm(kUnownedNonEnglishFormHtml, true, nullptr); | |
| 2675 } | |
| 2676 | |
| 2677 // Data that looks like an unowned form should NOT be matched unless an | |
| 2678 // additional indicator is present, such as title tag or url, to prevent false | |
| 2679 // positives. | |
| 2680 | |
| 2681 TEST_F(FormAutofillTest, UnmatchedFormNoURL) { | |
| 2682 TestUnmatchedUnownedForm(kUnownedUntitledFormHtml, nullptr); | |
| 2683 } | |
| 2684 | |
| 2685 TEST_F(FormAutofillTest, UnmatchedFormPathWithoutKeywords) { | |
| 2686 TestUnmatchedUnownedForm(kUnownedUntitledFormHtml, | |
| 2687 "http://example.test/path_without_keywords"); | |
| 2688 } | |
| 2689 | |
| 2690 TEST_F(FormAutofillTest, UnmatchedFormKeywordInQueryOnly) { | |
| 2691 TestUnmatchedUnownedForm(kUnownedUntitledFormHtml, | |
| 2692 "http://example.test/search?q=checkout+in+query"); | |
| 2693 } | |
| 2694 | |
| 2695 TEST_F(FormAutofillTest, UnmatchedFormTitleWithoutKeywords) { | |
| 2696 std::string wrong_title_html( | |
| 2697 "<TITLE>This title has nothing to do with autofill</TITLE>"); | |
| 2698 wrong_title_html += kUnownedUntitledFormHtml; | |
| 2699 TestUnmatchedUnownedForm(wrong_title_html.c_str(), nullptr); | |
| 2700 } | |
| 2701 | |
| 2702 TEST_F(FormAutofillTest, UnmatchedFormNonASCII) { | |
| 2703 std::string html("<HEAD><TITLE>Non-ASCII soft hyphen in the middle of " | |
| 2704 "keyword prevents a match here: check\xC2\xADout" | |
| 2705 "</TITLE></HEAD>"); | |
| 2706 html.append(kUnownedUntitledFormHtml); | |
| 2707 TestUnmatchedUnownedForm(html.c_str(), nullptr); | |
| 2708 } | |
| 2709 | |
| 2710 | |
| 2558 TEST_F(FormAutofillTest, Labels) { | 2711 TEST_F(FormAutofillTest, Labels) { |
| 2559 ExpectJohnSmithLabels( | 2712 ExpectJohnSmithLabels( |
| 2560 "<FORM name='TestForm' action='http://cnn.com' method='post'>" | 2713 "<FORM name='TestForm' action='http://cnn.com' method='post'>" |
| 2561 " <LABEL for='firstname'> First name: </LABEL>" | 2714 " <LABEL for='firstname'> First name: </LABEL>" |
| 2562 " <INPUT type='text' id='firstname' value='John'/>" | 2715 " <INPUT type='text' id='firstname' value='John'/>" |
| 2563 " <LABEL for='lastname'> Last name: </LABEL>" | 2716 " <LABEL for='lastname'> Last name: </LABEL>" |
| 2564 " <INPUT type='text' id='lastname' value='Smith'/>" | 2717 " <INPUT type='text' id='lastname' value='Smith'/>" |
| 2565 " <LABEL for='email'> Email: </LABEL>" | 2718 " <LABEL for='email'> Email: </LABEL>" |
| 2566 " <INPUT type='text' id='email' value='john@example.com'/>" | 2719 " <INPUT type='text' id='email' value='john@example.com'/>" |
| 2567 " <INPUT type='submit' name='reply-send' value='Send'/>" | 2720 " <INPUT type='submit' name='reply-send' value='Send'/>" |
| (...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4240 ASSERT_NE(nullptr, web_frame); | 4393 ASSERT_NE(nullptr, web_frame); |
| 4241 | 4394 |
| 4242 FormCache form_cache(*web_frame); | 4395 FormCache form_cache(*web_frame); |
| 4243 std::vector<FormData> forms = form_cache.ExtractNewForms(); | 4396 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 4244 EXPECT_EQ(test_case.expected_forms, forms.size()); | 4397 EXPECT_EQ(test_case.expected_forms, forms.size()); |
| 4245 } | 4398 } |
| 4246 } | 4399 } |
| 4247 | 4400 |
| 4248 } // namespace form_util | 4401 } // namespace form_util |
| 4249 } // namespace autofill | 4402 } // namespace autofill |
| OLD | NEW |