| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 " </SELECT>" | 97 " </SELECT>" |
| 98 " <SELECT id='select-unchanged'>" | 98 " <SELECT id='select-unchanged'>" |
| 99 " <OPTION value='CA' selected>California</OPTION>" | 99 " <OPTION value='CA' selected>California</OPTION>" |
| 100 " <OPTION value='TX'>Texas</OPTION>" | 100 " <OPTION value='TX'>Texas</OPTION>" |
| 101 " </SELECT>" | 101 " </SELECT>" |
| 102 " <TEXTAREA id='textarea'></TEXTAREA>" | 102 " <TEXTAREA id='textarea'></TEXTAREA>" |
| 103 " <TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" | 103 " <TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" |
| 104 " <INPUT type='submit' name='reply-send' value='Send'/>" | 104 " <INPUT type='submit' name='reply-send' value='Send'/>" |
| 105 "</FORM>"; | 105 "</FORM>"; |
| 106 | 106 |
| 107 // This constant uses a mixed-case title tag to be sure that the title match is |
| 108 // not case-sensitive. Other tests in this file use an all-lower title tag. |
| 107 const char kUnownedFormHtml[] = | 109 const char kUnownedFormHtml[] = |
| 108 "<HEAD><TITLE>enter shipping info</TITLE></HEAD>" | 110 "<HEAD><TITLE>Enter Shipping Info</TITLE></HEAD>" |
| 109 "<INPUT type='text' id='firstname'/>" | 111 "<INPUT type='text' id='firstname'/>" |
| 110 "<INPUT type='text' id='lastname'/>" | 112 "<INPUT type='text' id='lastname'/>" |
| 111 "<INPUT type='hidden' id='imhidden'/>" | 113 "<INPUT type='hidden' id='imhidden'/>" |
| 112 "<INPUT type='text' id='notempty' value='Hi'/>" | 114 "<INPUT type='text' id='notempty' value='Hi'/>" |
| 113 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" | 115 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" |
| 114 "<INPUT type='text' disabled='disabled' id='notenabled'/>" | 116 "<INPUT type='text' disabled='disabled' id='notenabled'/>" |
| 115 "<INPUT type='text' readonly id='readonly'/>" | 117 "<INPUT type='text' readonly id='readonly'/>" |
| 116 "<INPUT type='text' style='visibility: hidden'" | 118 "<INPUT type='text' style='visibility: hidden'" |
| 117 " id='invisible'/>" | 119 " id='invisible'/>" |
| 118 "<INPUT type='text' style='display: none' id='displaynone'/>" | 120 "<INPUT type='text' style='display: none' id='displaynone'/>" |
| 119 "<INPUT type='month' id='month'/>" | 121 "<INPUT type='month' id='month'/>" |
| 120 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" | 122 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" |
| 121 "<SELECT id='select'>" | 123 "<SELECT id='select'>" |
| 122 " <OPTION></OPTION>" | 124 " <OPTION></OPTION>" |
| 123 " <OPTION value='CA'>California</OPTION>" | 125 " <OPTION value='CA'>California</OPTION>" |
| 124 " <OPTION value='TX'>Texas</OPTION>" | 126 " <OPTION value='TX'>Texas</OPTION>" |
| 125 "</SELECT>" | 127 "</SELECT>" |
| 126 "<SELECT id='select-nonempty'>" | 128 "<SELECT id='select-nonempty'>" |
| 127 " <OPTION value='CA' selected>California</OPTION>" | 129 " <OPTION value='CA' selected>California</OPTION>" |
| 128 " <OPTION value='TX'>Texas</OPTION>" | 130 " <OPTION value='TX'>Texas</OPTION>" |
| 129 "</SELECT>" | 131 "</SELECT>" |
| 130 "<SELECT id='select-unchanged'>" | 132 "<SELECT id='select-unchanged'>" |
| 131 " <OPTION value='CA' selected>California</OPTION>" | 133 " <OPTION value='CA' selected>California</OPTION>" |
| 132 " <OPTION value='TX'>Texas</OPTION>" | 134 " <OPTION value='TX'>Texas</OPTION>" |
| 133 "</SELECT>" | 135 "</SELECT>" |
| 134 "<TEXTAREA id='textarea'></TEXTAREA>" | 136 "<TEXTAREA id='textarea'></TEXTAREA>" |
| 135 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" | 137 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" |
| 136 "<INPUT type='submit' name='reply-send' value='Send'/>"; | 138 "<INPUT type='submit' name='reply-send' value='Send'/>"; |
| 137 | 139 |
| 140 // This constant has no title tag, and should be passed to |
| 141 // LoadHTMLWithURLOverride to test the detection of unowned forms by URL. |
| 142 const char kUnownedUntitledFormHtml[] = |
| 143 "<INPUT type='text' id='firstname'/>" |
| 144 "<INPUT type='text' id='lastname'/>" |
| 145 "<INPUT type='hidden' id='imhidden'/>" |
| 146 "<INPUT type='text' id='notempty' value='Hi'/>" |
| 147 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" |
| 148 "<INPUT type='text' disabled='disabled' id='notenabled'/>" |
| 149 "<INPUT type='text' readonly id='readonly'/>" |
| 150 "<INPUT type='text' style='visibility: hidden'" |
| 151 " id='invisible'/>" |
| 152 "<INPUT type='text' style='display: none' id='displaynone'/>" |
| 153 "<INPUT type='month' id='month'/>" |
| 154 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" |
| 155 "<SELECT id='select'>" |
| 156 " <OPTION></OPTION>" |
| 157 " <OPTION value='CA'>California</OPTION>" |
| 158 " <OPTION value='TX'>Texas</OPTION>" |
| 159 "</SELECT>" |
| 160 "<SELECT id='select-nonempty'>" |
| 161 " <OPTION value='CA' selected>California</OPTION>" |
| 162 " <OPTION value='TX'>Texas</OPTION>" |
| 163 "</SELECT>" |
| 164 "<SELECT id='select-unchanged'>" |
| 165 " <OPTION value='CA' selected>California</OPTION>" |
| 166 " <OPTION value='TX'>Texas</OPTION>" |
| 167 "</SELECT>" |
| 168 "<TEXTAREA id='textarea'></TEXTAREA>" |
| 169 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" |
| 170 "<INPUT type='submit' name='reply-send' value='Send'/>"; |
| 171 |
| 172 // This constant does not have a title tag, but should match an unowned form |
| 173 // anyway because it is not English. |
| 174 const char kUnownedNonEnglishFormHtml[] = |
| 175 "<HTML LANG='fr'>" |
| 176 "<INPUT type='text' id='firstname'/>" |
| 177 "<INPUT type='text' id='lastname'/>" |
| 178 "<INPUT type='hidden' id='imhidden'/>" |
| 179 "<INPUT type='text' id='notempty' value='Hi'/>" |
| 180 "<INPUT type='text' autocomplete='off' id='noautocomplete'/>" |
| 181 "<INPUT type='text' disabled='disabled' id='notenabled'/>" |
| 182 "<INPUT type='text' readonly id='readonly'/>" |
| 183 "<INPUT type='text' style='visibility: hidden'" |
| 184 " id='invisible'/>" |
| 185 "<INPUT type='text' style='display: none' id='displaynone'/>" |
| 186 "<INPUT type='month' id='month'/>" |
| 187 "<INPUT type='month' id='month-nonempty' value='2011-12'/>" |
| 188 "<SELECT id='select'>" |
| 189 " <OPTION></OPTION>" |
| 190 " <OPTION value='CA'>California</OPTION>" |
| 191 " <OPTION value='TX'>Texas</OPTION>" |
| 192 "</SELECT>" |
| 193 "<SELECT id='select-nonempty'>" |
| 194 " <OPTION value='CA' selected>California</OPTION>" |
| 195 " <OPTION value='TX'>Texas</OPTION>" |
| 196 "</SELECT>" |
| 197 "<SELECT id='select-unchanged'>" |
| 198 " <OPTION value='CA' selected>California</OPTION>" |
| 199 " <OPTION value='TX'>Texas</OPTION>" |
| 200 "</SELECT>" |
| 201 "<TEXTAREA id='textarea'></TEXTAREA>" |
| 202 "<TEXTAREA id='textarea-nonempty'>Go away!</TEXTAREA>" |
| 203 "<INPUT type='submit' name='reply-send' value='Send'/>" |
| 204 "</HTML>"; |
| 205 |
| 138 std::string RetrievalMethodToString( | 206 std::string RetrievalMethodToString( |
| 139 const WebElementDescriptor::RetrievalMethod& method) { | 207 const WebElementDescriptor::RetrievalMethod& method) { |
| 140 switch (method) { | 208 switch (method) { |
| 141 case WebElementDescriptor::CSS_SELECTOR: | 209 case WebElementDescriptor::CSS_SELECTOR: |
| 142 return "CSS_SELECTOR"; | 210 return "CSS_SELECTOR"; |
| 143 case WebElementDescriptor::ID: | 211 case WebElementDescriptor::ID: |
| 144 return "ID"; | 212 return "ID"; |
| 145 case WebElementDescriptor::NONE: | 213 case WebElementDescriptor::NONE: |
| 146 return "NONE"; | 214 return "NONE"; |
| 147 } | 215 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 } | 324 } |
| 257 | 325 |
| 258 typedef void (*FillFormFunction)(const FormData& form, | 326 typedef void (*FillFormFunction)(const FormData& form, |
| 259 const WebFormControlElement& element); | 327 const WebFormControlElement& element); |
| 260 | 328 |
| 261 typedef WebString (*GetValueFunction)(WebFormControlElement element); | 329 typedef WebString (*GetValueFunction)(WebFormControlElement element); |
| 262 | 330 |
| 263 // Test FormFillxxx functions. | 331 // Test FormFillxxx functions. |
| 264 void TestFormFillFunctions(const char* html, | 332 void TestFormFillFunctions(const char* html, |
| 265 bool unowned, | 333 bool unowned, |
| 334 const char* url_override, |
| 266 const AutofillFieldCase* field_cases, | 335 const AutofillFieldCase* field_cases, |
| 267 size_t number_of_field_cases, | 336 size_t number_of_field_cases, |
| 268 FillFormFunction fill_form_function, | 337 FillFormFunction fill_form_function, |
| 269 GetValueFunction get_value_function) { | 338 GetValueFunction get_value_function) { |
| 270 LoadHTML(html); | 339 if (url_override) |
| 340 LoadHTMLWithUrlOverride(html, url_override); |
| 341 else |
| 342 LoadHTML(html); |
| 271 | 343 |
| 272 WebFrame* web_frame = GetMainFrame(); | 344 WebFrame* web_frame = GetMainFrame(); |
| 273 ASSERT_NE(nullptr, web_frame); | 345 ASSERT_NE(nullptr, web_frame); |
| 274 | 346 |
| 275 FormCache form_cache(*web_frame); | 347 FormCache form_cache(*web_frame); |
| 276 std::vector<FormData> forms = form_cache.ExtractNewForms(); | 348 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 277 ASSERT_EQ(1U, forms.size()); | 349 ASSERT_EQ(1U, forms.size()); |
| 278 | 350 |
| 279 // Get the input element we want to find. | 351 // Get the input element we want to find. |
| 280 WebInputElement input_element = GetInputElementById("firstname"); | 352 WebInputElement input_element = GetInputElementById("firstname"); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 WebFormControlElement GetFormControlElementById(const WebString& id) { | 427 WebFormControlElement GetFormControlElementById(const WebString& id) { |
| 356 return GetMainFrame()->document().getElementById( | 428 return GetMainFrame()->document().getElementById( |
| 357 id).to<WebFormControlElement>(); | 429 id).to<WebFormControlElement>(); |
| 358 } | 430 } |
| 359 | 431 |
| 360 WebInputElement GetInputElementById(const WebString& id) { | 432 WebInputElement GetInputElementById(const WebString& id) { |
| 361 return GetMainFrame()->document().getElementById( | 433 return GetMainFrame()->document().getElementById( |
| 362 id).to<WebInputElement>(); | 434 id).to<WebInputElement>(); |
| 363 } | 435 } |
| 364 | 436 |
| 365 void TestFillForm(const char* html, bool unowned) { | 437 void TestFillForm(const char* html, bool unowned, const char* url_override) { |
| 366 static const AutofillFieldCase field_cases[] = { | 438 static const AutofillFieldCase field_cases[] = { |
| 367 // fields: form_control_type, name, initial_value, autocomplete_attribute, | 439 // fields: form_control_type, name, initial_value, autocomplete_attribute, |
| 368 // should_be_autofilled, autofill_value, expected_value | 440 // should_be_autofilled, autofill_value, expected_value |
| 369 | 441 |
| 370 // Regular empty fields (firstname & lastname) should be autofilled. | 442 // Regular empty fields (firstname & lastname) should be autofilled. |
| 371 {"text", | 443 {"text", |
| 372 "firstname", | 444 "firstname", |
| 373 "", | 445 "", |
| 374 "", | 446 "", |
| 375 true, | 447 true, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 "some multi-\nline value"}, | 488 "some multi-\nline value"}, |
| 417 // Non-empty textarea elements should not be autofilled. | 489 // Non-empty textarea elements should not be autofilled. |
| 418 {"textarea", | 490 {"textarea", |
| 419 "textarea-nonempty", | 491 "textarea-nonempty", |
| 420 "Go\naway!", | 492 "Go\naway!", |
| 421 "", | 493 "", |
| 422 false, | 494 false, |
| 423 "some multi-\nline value", | 495 "some multi-\nline value", |
| 424 "Go\naway!"}, | 496 "Go\naway!"}, |
| 425 }; | 497 }; |
| 426 TestFormFillFunctions(html, unowned, field_cases, arraysize(field_cases), | 498 TestFormFillFunctions(html, unowned, url_override, |
| 499 field_cases, arraysize(field_cases), |
| 427 FillForm, &GetValueWrapper); | 500 FillForm, &GetValueWrapper); |
| 428 // Verify preview selection. | 501 // Verify preview selection. |
| 429 WebInputElement firstname = GetInputElementById("firstname"); | 502 WebInputElement firstname = GetInputElementById("firstname"); |
| 430 EXPECT_EQ(16, firstname.selectionStart()); | 503 EXPECT_EQ(16, firstname.selectionStart()); |
| 431 EXPECT_EQ(16, firstname.selectionEnd()); | 504 EXPECT_EQ(16, firstname.selectionEnd()); |
| 432 } | 505 } |
| 433 | 506 |
| 434 void TestPreviewForm(const char* html, bool unowned) { | 507 void TestPreviewForm(const char* html, bool unowned, |
| 508 const char* url_override) { |
| 435 static const AutofillFieldCase field_cases[] = { | 509 static const AutofillFieldCase field_cases[] = { |
| 436 // Normal empty fields should be previewed. | 510 // Normal empty fields should be previewed. |
| 437 {"text", | 511 {"text", |
| 438 "firstname", | 512 "firstname", |
| 439 "", | 513 "", |
| 440 "", | 514 "", |
| 441 true, | 515 true, |
| 442 "suggested firstname", | 516 "suggested firstname", |
| 443 "suggested firstname"}, | 517 "suggested firstname"}, |
| 444 {"text", | 518 {"text", |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 "suggested multi-\nline value"}, | 562 "suggested multi-\nline value"}, |
| 489 // Nonempty textarea elements should not be previewed. | 563 // Nonempty textarea elements should not be previewed. |
| 490 {"textarea", | 564 {"textarea", |
| 491 "textarea-nonempty", | 565 "textarea-nonempty", |
| 492 "Go\naway!", | 566 "Go\naway!", |
| 493 "", | 567 "", |
| 494 false, | 568 false, |
| 495 "suggested multi-\nline value", | 569 "suggested multi-\nline value", |
| 496 ""}, | 570 ""}, |
| 497 }; | 571 }; |
| 498 TestFormFillFunctions(html, unowned, field_cases, arraysize(field_cases), | 572 TestFormFillFunctions(html, unowned, url_override, |
| 573 field_cases, arraysize(field_cases), |
| 499 &PreviewForm, &GetSuggestedValueWrapper); | 574 &PreviewForm, &GetSuggestedValueWrapper); |
| 500 | 575 |
| 501 // Verify preview selection. | 576 // Verify preview selection. |
| 502 WebInputElement firstname = GetInputElementById("firstname"); | 577 WebInputElement firstname = GetInputElementById("firstname"); |
| 503 EXPECT_EQ(0, firstname.selectionStart()); | 578 EXPECT_EQ(0, firstname.selectionStart()); |
| 504 EXPECT_EQ(19, firstname.selectionEnd()); | 579 EXPECT_EQ(19, firstname.selectionEnd()); |
| 505 } | 580 } |
| 506 | 581 |
| 582 void TestUnmatchedUnownedForm(const char* html, const char* url_override) { |
| 583 if (url_override) |
| 584 LoadHTMLWithUrlOverride(html, url_override); |
| 585 else |
| 586 LoadHTML(html); |
| 587 |
| 588 WebFrame* web_frame = GetMainFrame(); |
| 589 ASSERT_NE(nullptr, web_frame); |
| 590 |
| 591 FormCache form_cache(*web_frame); |
| 592 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 593 ASSERT_EQ(0U, forms.size()); |
| 594 } |
| 595 |
| 507 void TestFindFormForInputElement(const char* html, bool unowned) { | 596 void TestFindFormForInputElement(const char* html, bool unowned) { |
| 508 LoadHTML(html); | 597 LoadHTML(html); |
| 509 WebFrame* web_frame = GetMainFrame(); | 598 WebFrame* web_frame = GetMainFrame(); |
| 510 ASSERT_NE(nullptr, web_frame); | 599 ASSERT_NE(nullptr, web_frame); |
| 511 | 600 |
| 512 FormCache form_cache(*web_frame); | 601 FormCache form_cache(*web_frame); |
| 513 std::vector<FormData> forms = form_cache.ExtractNewForms(); | 602 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 514 ASSERT_EQ(1U, forms.size()); | 603 ASSERT_EQ(1U, forms.size()); |
| 515 | 604 |
| 516 // Get the input element we want to find. | 605 // Get the input element we want to find. |
| (...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2501 "<TEXTAREA id='street-address'>" | 2590 "<TEXTAREA id='street-address'>" |
| 2502 "123 Fantasy Ln. " | 2591 "123 Fantasy Ln. " |
| 2503 "Apt. 42" | 2592 "Apt. 42" |
| 2504 "</TEXTAREA>" | 2593 "</TEXTAREA>" |
| 2505 "<INPUT type='submit' name='reply-send' value='Send'/>", | 2594 "<INPUT type='submit' name='reply-send' value='Send'/>", |
| 2506 true); | 2595 true); |
| 2507 } | 2596 } |
| 2508 | 2597 |
| 2509 // Test regular FillForm function. | 2598 // Test regular FillForm function. |
| 2510 TEST_F(FormAutofillTest, FillForm) { | 2599 TEST_F(FormAutofillTest, FillForm) { |
| 2511 TestFillForm(kFormHtml, false); | 2600 TestFillForm(kFormHtml, false, nullptr); |
| 2512 } | 2601 } |
| 2513 | 2602 |
| 2514 TEST_F(FormAutofillTest, FillFormForUnownedForm) { | 2603 TEST_F(FormAutofillTest, FillFormForUnownedForm) { |
| 2515 TestFillForm(kUnownedFormHtml, true); | 2604 TestFillForm(kUnownedFormHtml, true, nullptr); |
| 2605 } |
| 2606 |
| 2607 TEST_F(FormAutofillTest, FillFormForUnownedUntitledForm) { |
| 2608 TestFillForm(kUnownedUntitledFormHtml, true, |
| 2609 "http://example.test/checkout_flow"); |
| 2610 } |
| 2611 |
| 2612 TEST_F(FormAutofillTest, FillFormForUnownedNonEnglishForm) { |
| 2613 TestFillForm(kUnownedNonEnglishFormHtml, true, nullptr); |
| 2614 } |
| 2615 |
| 2616 TEST_F(FormAutofillTest, FillFormForUnownedNonASCIIForm) { |
| 2617 std::string html("<HEAD><TITLE>accented latin: \xC3\xA0, thai: \xE0\xB8\x81, " |
| 2618 "control: \x04, nbsp: \xEF\xBB\xBF, non-BMP: \xF0\x9F\x8C\x80; This " |
| 2619 "should match a CHECKOUT flow despite the non-ASCII chars" |
| 2620 "</TITLE></HEAD>"); |
| 2621 html.append(kUnownedUntitledFormHtml); |
| 2622 TestFillForm(html.c_str(), true, nullptr); |
| 2516 } | 2623 } |
| 2517 | 2624 |
| 2518 TEST_F(FormAutofillTest, FillFormIncludingNonFocusableElements) { | 2625 TEST_F(FormAutofillTest, FillFormIncludingNonFocusableElements) { |
| 2519 static const AutofillFieldCase field_cases[] = { | 2626 static const AutofillFieldCase field_cases[] = { |
| 2520 // fields: form_control_type, name, initial_value, autocomplete_attribute, | 2627 // fields: form_control_type, name, initial_value, autocomplete_attribute, |
| 2521 // should_be_autofilled, autofill_value, expected_value | 2628 // should_be_autofilled, autofill_value, expected_value |
| 2522 | 2629 |
| 2523 // Regular empty fields (firstname & lastname) should be autofilled. | 2630 // Regular empty fields (firstname & lastname) should be autofilled. |
| 2524 {"text", | 2631 {"text", |
| 2525 "firstname", | 2632 "firstname", |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2587 "some multi-\nline value"}, | 2694 "some multi-\nline value"}, |
| 2588 // Nonempty textarea elements should be overridden. | 2695 // Nonempty textarea elements should be overridden. |
| 2589 {"textarea", | 2696 {"textarea", |
| 2590 "textarea-nonempty", | 2697 "textarea-nonempty", |
| 2591 "Go\naway!", | 2698 "Go\naway!", |
| 2592 "", | 2699 "", |
| 2593 true, | 2700 true, |
| 2594 "some multi-\nline value", | 2701 "some multi-\nline value", |
| 2595 "some multi-\nline value"}, | 2702 "some multi-\nline value"}, |
| 2596 }; | 2703 }; |
| 2597 TestFormFillFunctions(kFormHtml, false, field_cases, arraysize(field_cases), | 2704 TestFormFillFunctions(kFormHtml, false, nullptr, |
| 2705 field_cases, arraysize(field_cases), |
| 2598 &FillFormIncludingNonFocusableElementsWrapper, | 2706 &FillFormIncludingNonFocusableElementsWrapper, |
| 2599 &GetValueWrapper); | 2707 &GetValueWrapper); |
| 2600 } | 2708 } |
| 2601 | 2709 |
| 2602 TEST_F(FormAutofillTest, PreviewForm) { | 2710 TEST_F(FormAutofillTest, PreviewForm) { |
| 2603 TestPreviewForm(kFormHtml, false); | 2711 TestPreviewForm(kFormHtml, false, nullptr); |
| 2604 } | 2712 } |
| 2605 | 2713 |
| 2606 TEST_F(FormAutofillTest, PreviewFormForUnownedForm) { | 2714 TEST_F(FormAutofillTest, PreviewFormForUnownedForm) { |
| 2607 TestPreviewForm(kUnownedFormHtml, true); | 2715 TestPreviewForm(kUnownedFormHtml, true, nullptr); |
| 2608 } | 2716 } |
| 2609 | 2717 |
| 2718 TEST_F(FormAutofillTest, PreviewFormForUnownedUntitledForm) { |
| 2719 // This test uses a mixed-case URL to be sure that the url match is not |
| 2720 // case-sensitive. |
| 2721 TestPreviewForm(kUnownedUntitledFormHtml, true, |
| 2722 "http://example.test/Enter_Shipping_Address/"); |
| 2723 } |
| 2724 |
| 2725 TEST_F(FormAutofillTest, PreviewFormForUnownedNonEnglishForm) { |
| 2726 TestPreviewForm(kUnownedNonEnglishFormHtml, true, nullptr); |
| 2727 } |
| 2728 |
| 2729 // Data that looks like an unowned form should NOT be matched unless an |
| 2730 // additional indicator is present, such as title tag or url, to prevent false |
| 2731 // positives. |
| 2732 |
| 2733 TEST_F(FormAutofillTest, UnmatchedFormNoURL) { |
| 2734 TestUnmatchedUnownedForm(kUnownedUntitledFormHtml, nullptr); |
| 2735 } |
| 2736 |
| 2737 TEST_F(FormAutofillTest, UnmatchedFormPathWithoutKeywords) { |
| 2738 TestUnmatchedUnownedForm(kUnownedUntitledFormHtml, |
| 2739 "http://example.test/path_without_keywords"); |
| 2740 } |
| 2741 |
| 2742 TEST_F(FormAutofillTest, UnmatchedFormKeywordInQueryOnly) { |
| 2743 TestUnmatchedUnownedForm(kUnownedUntitledFormHtml, |
| 2744 "http://example.test/search?q=checkout+in+query"); |
| 2745 } |
| 2746 |
| 2747 TEST_F(FormAutofillTest, UnmatchedFormTitleWithoutKeywords) { |
| 2748 std::string wrong_title_html( |
| 2749 "<TITLE>This title has nothing to do with autofill</TITLE>"); |
| 2750 wrong_title_html += kUnownedUntitledFormHtml; |
| 2751 TestUnmatchedUnownedForm(wrong_title_html.c_str(), nullptr); |
| 2752 } |
| 2753 |
| 2754 TEST_F(FormAutofillTest, UnmatchedFormNonASCII) { |
| 2755 std::string html("<HEAD><TITLE>Non-ASCII soft hyphen in the middle of " |
| 2756 "keyword prevents a match here: check\xC2\xADout" |
| 2757 "</TITLE></HEAD>"); |
| 2758 html.append(kUnownedUntitledFormHtml); |
| 2759 TestUnmatchedUnownedForm(html.c_str(), nullptr); |
| 2760 } |
| 2761 |
| 2762 |
| 2610 TEST_F(FormAutofillTest, Labels) { | 2763 TEST_F(FormAutofillTest, Labels) { |
| 2611 ExpectJohnSmithLabels( | 2764 ExpectJohnSmithLabels( |
| 2612 "<FORM name='TestForm' action='http://cnn.com' method='post'>" | 2765 "<FORM name='TestForm' action='http://cnn.com' method='post'>" |
| 2613 " <LABEL for='firstname'> First name: </LABEL>" | 2766 " <LABEL for='firstname'> First name: </LABEL>" |
| 2614 " <INPUT type='text' id='firstname' value='John'/>" | 2767 " <INPUT type='text' id='firstname' value='John'/>" |
| 2615 " <LABEL for='lastname'> Last name: </LABEL>" | 2768 " <LABEL for='lastname'> Last name: </LABEL>" |
| 2616 " <INPUT type='text' id='lastname' value='Smith'/>" | 2769 " <INPUT type='text' id='lastname' value='Smith'/>" |
| 2617 " <LABEL for='email'> Email: </LABEL>" | 2770 " <LABEL for='email'> Email: </LABEL>" |
| 2618 " <INPUT type='text' id='email' value='john@example.com'/>" | 2771 " <INPUT type='text' id='email' value='john@example.com'/>" |
| 2619 " <INPUT type='submit' name='reply-send' value='Send'/>" | 2772 " <INPUT type='submit' name='reply-send' value='Send'/>" |
| (...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4298 ASSERT_NE(nullptr, web_frame); | 4451 ASSERT_NE(nullptr, web_frame); |
| 4299 | 4452 |
| 4300 FormCache form_cache(*web_frame); | 4453 FormCache form_cache(*web_frame); |
| 4301 std::vector<FormData> forms = form_cache.ExtractNewForms(); | 4454 std::vector<FormData> forms = form_cache.ExtractNewForms(); |
| 4302 EXPECT_EQ(test_case.expected_forms, forms.size()); | 4455 EXPECT_EQ(test_case.expected_forms, forms.size()); |
| 4303 } | 4456 } |
| 4304 } | 4457 } |
| 4305 | 4458 |
| 4306 } // namespace form_util | 4459 } // namespace form_util |
| 4307 } // namespace autofill | 4460 } // namespace autofill |
| OLD | NEW |