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 "base/strings/string_util.h" | 5 #include "base/strings/string_util.h" |
6 #include "base/strings/utf_string_conversions.h" | 6 #include "base/strings/utf_string_conversions.h" |
7 #include "chrome/test/base/chrome_render_view_test.h" | 7 #include "chrome/test/base/chrome_render_view_test.h" |
8 #include "components/autofill/content/common/autofill_messages.h" | 8 #include "components/autofill/content/common/autofill_messages.h" |
9 #include "components/autofill/content/renderer/autofill_agent.h" | 9 #include "components/autofill/content/renderer/autofill_agent.h" |
10 #include "components/autofill/content/renderer/form_autofill_util.h" | 10 #include "components/autofill/content/renderer/form_autofill_util.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 const char kPasswordName[] = "password"; | 42 const char kPasswordName[] = "password"; |
43 | 43 |
44 const char kAliceUsername[] = "alice"; | 44 const char kAliceUsername[] = "alice"; |
45 const char kAlicePassword[] = "password"; | 45 const char kAlicePassword[] = "password"; |
46 const char kBobUsername[] = "bob"; | 46 const char kBobUsername[] = "bob"; |
47 const char kBobPassword[] = "secret"; | 47 const char kBobPassword[] = "secret"; |
48 const char kCarolUsername[] = "Carol"; | 48 const char kCarolUsername[] = "Carol"; |
49 const char kCarolPassword[] = "test"; | 49 const char kCarolPassword[] = "test"; |
50 const char kCarolAlternateUsername[] = "RealCarolUsername"; | 50 const char kCarolAlternateUsername[] = "RealCarolUsername"; |
51 | 51 |
52 | |
53 const char kFormHTML[] = | 52 const char kFormHTML[] = |
54 "<FORM name='LoginTestForm' action='http://www.bidule.com'>" | 53 "<FORM name='LoginTestForm' action='http://www.bidule.com'>" |
55 " <INPUT type='text' id='username'/>" | 54 " <INPUT type='text' id='username'/>" |
56 " <INPUT type='password' id='password'/>" | 55 " <INPUT type='password' id='password'/>" |
57 " <INPUT type='submit' value='Login'/>" | 56 " <INPUT type='submit' value='Login'/>" |
58 "</FORM>"; | 57 "</FORM>"; |
59 | 58 |
60 const char kVisibleFormHTML[] = | 59 const char kVisibleFormHTML[] = |
61 "<head> <style> form {display: inline;} </style> </head>" | 60 "<head> <style> form {display: inline;} </style> </head>" |
62 "<body>" | 61 "<body>" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 " usernameOnchangeCalled = false;" | 149 " usernameOnchangeCalled = false;" |
151 " passwordOnchangeCalled = false;" | 150 " passwordOnchangeCalled = false;" |
152 " document.getElementById('username').onchange = function() {" | 151 " document.getElementById('username').onchange = function() {" |
153 " usernameOnchangeCalled = true;" | 152 " usernameOnchangeCalled = true;" |
154 " };" | 153 " };" |
155 " document.getElementById('password').onchange = function() {" | 154 " document.getElementById('password').onchange = function() {" |
156 " passwordOnchangeCalled = true;" | 155 " passwordOnchangeCalled = true;" |
157 " };" | 156 " };" |
158 "</script>"; | 157 "</script>"; |
159 | 158 |
| 159 // Sets the "readonly" attribute of |element| to the value given by |read_only|. |
| 160 void SetElementReadOnly(WebInputElement& element, bool read_only) { |
| 161 element.setAttribute(WebString::fromUTF8("readonly"), |
| 162 read_only ? WebString::fromUTF8("true") : WebString()); |
| 163 } |
| 164 |
160 } // namespace | 165 } // namespace |
161 | 166 |
162 namespace autofill { | 167 namespace autofill { |
163 | 168 |
164 class PasswordAutofillAgentTest : public ChromeRenderViewTest { | 169 class PasswordAutofillAgentTest : public ChromeRenderViewTest { |
165 public: | 170 public: |
166 PasswordAutofillAgentTest() { | 171 PasswordAutofillAgentTest() { |
167 } | 172 } |
168 | 173 |
169 // Simulates the fill password form message being sent to the renderer. | 174 // Simulates the fill password form message being sent to the renderer. |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 // autocomplete. | 454 // autocomplete. |
450 SimulateOnFillPasswordForm(fill_data_); | 455 SimulateOnFillPasswordForm(fill_data_); |
451 | 456 |
452 // The username and password should have been autocompleted. | 457 // The username and password should have been autocompleted. |
453 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 458 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); |
454 } | 459 } |
455 | 460 |
456 // Tests that if a password is marked as readonly, neither field is autofilled | 461 // Tests that if a password is marked as readonly, neither field is autofilled |
457 // on page load. | 462 // on page load. |
458 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) { | 463 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) { |
459 password_element_.setAttribute(WebString::fromUTF8("readonly"), | 464 SetElementReadOnly(password_element_, true); |
460 WebString::fromUTF8("true")); | |
461 | 465 |
462 // Simulate the browser sending back the login info, it triggers the | 466 // Simulate the browser sending back the login info, it triggers the |
463 // autocomplete. | 467 // autocomplete. |
464 SimulateOnFillPasswordForm(fill_data_); | 468 SimulateOnFillPasswordForm(fill_data_); |
465 | 469 |
466 CheckTextFieldsState(std::string(), false, std::string(), false); | 470 CheckTextFieldsState(std::string(), false, std::string(), false); |
467 } | 471 } |
468 | 472 |
469 // Can still fill a password field if the username is set to a value that | 473 // Can still fill a password field if the username is set to a value that |
470 // matches. | 474 // matches. |
471 TEST_F(PasswordAutofillAgentTest, | 475 TEST_F(PasswordAutofillAgentTest, |
472 AutocompletePasswordForReadonlyUsernameMatched) { | 476 AutocompletePasswordForReadonlyUsernameMatched) { |
473 username_element_.setValue(username3_); | 477 username_element_.setValue(username3_); |
474 username_element_.setAttribute(WebString::fromUTF8("readonly"), | 478 SetElementReadOnly(username_element_, true); |
475 WebString::fromUTF8("true")); | |
476 | 479 |
477 // Filled even though username is not the preferred match. | 480 // Filled even though username is not the preferred match. |
478 SimulateOnFillPasswordForm(fill_data_); | 481 SimulateOnFillPasswordForm(fill_data_); |
479 CheckTextFieldsState(UTF16ToUTF8(username3_), false, | 482 CheckTextFieldsState(UTF16ToUTF8(username3_), false, |
480 UTF16ToUTF8(password3_), true); | 483 UTF16ToUTF8(password3_), true); |
481 } | 484 } |
482 | 485 |
483 // If a username field is empty and readonly, don't autofill. | 486 // If a username field is empty and readonly, don't autofill. |
484 TEST_F(PasswordAutofillAgentTest, | 487 TEST_F(PasswordAutofillAgentTest, |
485 NoAutocompletePasswordForReadonlyUsernameUnmatched) { | 488 NoAutocompletePasswordForReadonlyUsernameUnmatched) { |
486 username_element_.setValue(WebString::fromUTF8("")); | 489 username_element_.setValue(WebString::fromUTF8("")); |
487 username_element_.setAttribute(WebString::fromUTF8("readonly"), | 490 SetElementReadOnly(username_element_, true); |
488 WebString::fromUTF8("true")); | |
489 | 491 |
490 SimulateOnFillPasswordForm(fill_data_); | 492 SimulateOnFillPasswordForm(fill_data_); |
491 CheckTextFieldsState(std::string(), false, std::string(), false); | 493 CheckTextFieldsState(std::string(), false, std::string(), false); |
492 } | 494 } |
493 | 495 |
494 // Tests that having a non-matching username precludes the autocomplete. | 496 // Tests that having a non-matching username precludes the autocomplete. |
495 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) { | 497 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) { |
496 username_element_.setValue(WebString::fromUTF8("bogus")); | 498 username_element_.setValue(WebString::fromUTF8("bogus")); |
497 | 499 |
498 // Simulate the browser sending back the login info, it triggers the | 500 // Simulate the browser sending back the login info, it triggers the |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), | 1011 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), |
1010 &username_onchange_called)); | 1012 &username_onchange_called)); |
1011 EXPECT_EQ(1, username_onchange_called); | 1013 EXPECT_EQ(1, username_onchange_called); |
1012 ASSERT_TRUE( | 1014 ASSERT_TRUE( |
1013 ExecuteJavaScriptAndReturnIntValue( | 1015 ExecuteJavaScriptAndReturnIntValue( |
1014 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), | 1016 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), |
1015 &password_onchange_called)); | 1017 &password_onchange_called)); |
1016 EXPECT_EQ(1, password_onchange_called); | 1018 EXPECT_EQ(1, password_onchange_called); |
1017 } | 1019 } |
1018 | 1020 |
| 1021 // Tests that |AcceptSuggestion| properly fills the username and password. |
| 1022 TEST_F(PasswordAutofillAgentTest, AcceptSuggestion) { |
| 1023 // Simulate the browser sending the login info, but set |wait_for_username| |
| 1024 // to prevent the form from being immediately filled. |
| 1025 fill_data_.wait_for_username = true; |
| 1026 SimulateOnFillPasswordForm(fill_data_); |
| 1027 |
| 1028 // Neither field should have been autocompleted. |
| 1029 CheckTextFieldsDOMState(std::string(), false, std::string(), false); |
| 1030 |
| 1031 // If the password field is not autocompletable, it should not be affected. |
| 1032 SetElementReadOnly(password_element_, true); |
| 1033 EXPECT_FALSE(password_autofill_->AcceptSuggestion( |
| 1034 username_element_, kAliceUsername, kAlicePassword)); |
| 1035 CheckTextFieldsDOMState(std::string(), false, std::string(), false); |
| 1036 SetElementReadOnly(password_element_, false); |
| 1037 |
| 1038 // After accepting the suggestion, both fields should be autocompleted. |
| 1039 EXPECT_TRUE(password_autofill_->AcceptSuggestion( |
| 1040 username_element_, kAliceUsername, kAlicePassword)); |
| 1041 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
| 1042 |
| 1043 // Try accepting a suggestion with a password different from the one that was |
| 1044 // initially sent to the renderer. |
| 1045 EXPECT_TRUE(password_autofill_->AcceptSuggestion( |
| 1046 username_element_, kBobUsername, kCarolPassword)); |
| 1047 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true); |
| 1048 } |
| 1049 |
1019 } // namespace autofill | 1050 } // namespace autofill |
OLD | NEW |