| 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 |