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 "components/autofill/content/renderer/password_autofill_agent.h" | 5 #include "components/autofill/content/renderer/password_autofill_agent.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 const char kJavaScriptClick[] = | 170 const char kJavaScriptClick[] = |
171 "var event = new MouseEvent('click', {" | 171 "var event = new MouseEvent('click', {" |
172 " 'view': window," | 172 " 'view': window," |
173 " 'bubbles': true," | 173 " 'bubbles': true," |
174 " 'cancelable': true" | 174 " 'cancelable': true" |
175 "});" | 175 "});" |
176 "var form = document.getElementById('myform1');" | 176 "var form = document.getElementById('myform1');" |
177 "form.dispatchEvent(event);" | 177 "form.dispatchEvent(event);" |
178 "console.log('clicked!');"; | 178 "console.log('clicked!');"; |
179 | 179 |
180 const char kOnChangeDetectionScript[] = | |
181 "<script>" | |
182 " usernameOnchangeCalled = false;" | |
183 " passwordOnchangeCalled = false;" | |
184 " document.getElementById('username').onchange = function() {" | |
185 " usernameOnchangeCalled = true;" | |
186 " };" | |
187 " document.getElementById('password').onchange = function() {" | |
188 " passwordOnchangeCalled = true;" | |
189 " };" | |
190 "</script>"; | |
191 | |
192 const char kFormHTMLWithTwoTextFields[] = | 180 const char kFormHTMLWithTwoTextFields[] = |
193 "<FORM name='LoginTestForm' id='LoginTestForm' " | 181 "<FORM name='LoginTestForm' id='LoginTestForm' " |
194 "action='http://www.bidule.com'>" | 182 "action='http://www.bidule.com'>" |
195 " <INPUT type='text' id='username'/>" | 183 " <INPUT type='text' id='username'/>" |
196 " <INPUT type='text' id='email'/>" | 184 " <INPUT type='text' id='email'/>" |
197 " <INPUT type='password' id='password'/>" | 185 " <INPUT type='password' id='password'/>" |
198 " <INPUT type='submit' value='Login'/>" | 186 " <INPUT type='submit' value='Login'/>" |
199 "</FORM>"; | 187 "</FORM>"; |
200 | 188 |
201 const char kPasswordChangeFormHTML[] = | 189 const char kPasswordChangeFormHTML[] = |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 ASSERT_TRUE(fake_driver_.called_inpage_navigation()); | 532 ASSERT_TRUE(fake_driver_.called_inpage_navigation()); |
545 ASSERT_TRUE( | 533 ASSERT_TRUE( |
546 static_cast<bool>(fake_driver_.password_form_inpage_navigation())); | 534 static_cast<bool>(fake_driver_.password_form_inpage_navigation())); |
547 const autofill::PasswordForm& form = | 535 const autofill::PasswordForm& form = |
548 *(fake_driver_.password_form_inpage_navigation()); | 536 *(fake_driver_.password_form_inpage_navigation()); |
549 EXPECT_EQ(ASCIIToUTF16(username_value), form.username_value); | 537 EXPECT_EQ(ASCIIToUTF16(username_value), form.username_value); |
550 EXPECT_EQ(ASCIIToUTF16(password_value), form.password_value); | 538 EXPECT_EQ(ASCIIToUTF16(password_value), form.password_value); |
551 EXPECT_EQ(ASCIIToUTF16(new_password_value), form.new_password_value); | 539 EXPECT_EQ(ASCIIToUTF16(new_password_value), form.new_password_value); |
552 } | 540 } |
553 | 541 |
542 void CheckIfEventsAreCalled(const std::vector<base::string16>& checkers, | |
543 bool expected) { | |
544 for (const base::string16& variable : checkers) { | |
545 int value; | |
546 EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(variable, &value)) | |
547 << variable; | |
548 EXPECT_EQ(expected, value == 1) << variable; | |
549 } | |
550 } | |
551 | |
554 bool GetCalledShowPasswordGenerationPopup() { | 552 bool GetCalledShowPasswordGenerationPopup() { |
555 fake_pw_client_.Flush(); | 553 fake_pw_client_.Flush(); |
556 return fake_pw_client_.called_show_pw_generation_popup(); | 554 return fake_pw_client_.called_show_pw_generation_popup(); |
557 } | 555 } |
558 | 556 |
559 void BindPasswordManagerDriver(mojo::ScopedMessagePipeHandle handle) { | 557 void BindPasswordManagerDriver(mojo::ScopedMessagePipeHandle handle) { |
560 fake_driver_.BindRequest( | 558 fake_driver_.BindRequest( |
561 mojo::MakeRequest<mojom::PasswordManagerDriver>(std::move(handle))); | 559 mojo::MakeRequest<mojom::PasswordManagerDriver>(std::move(handle))); |
562 } | 560 } |
563 | 561 |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
908 | 906 |
909 // Verfies that a DOM-activated UI event will not cause an autofill. | 907 // Verfies that a DOM-activated UI event will not cause an autofill. |
910 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) { | 908 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) { |
911 // Trigger the initial autocomplete. | 909 // Trigger the initial autocomplete. |
912 SimulateOnFillPasswordForm(fill_data_); | 910 SimulateOnFillPasswordForm(fill_data_); |
913 | 911 |
914 ExecuteJavaScriptForTests(kJavaScriptClick); | 912 ExecuteJavaScriptForTests(kJavaScriptClick); |
915 CheckTextFieldsDOMState(kAliceUsername, true, "", true); | 913 CheckTextFieldsDOMState(kAliceUsername, true, "", true); |
916 } | 914 } |
917 | 915 |
918 // Verifies that password autofill triggers onChange events in JavaScript for | 916 // Verifies that password autofill triggers events in JavaScript for forms that |
919 // forms that are filled on page load. | 917 // are filled on page load. |
920 TEST_F(PasswordAutofillAgentTest, | 918 TEST_F(PasswordAutofillAgentTest, |
921 PasswordAutofillTriggersOnChangeEventsOnLoad) { | 919 PasswordAutofillTriggersOnChangeEventsOnLoad) { |
922 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript; | 920 std::vector<base::string16> username_event_checkers; |
921 std::vector<base::string16> password_event_checkers; | |
922 std::string events_registration_script = | |
923 CreateScriptToRegisterListeners(kUsernameName, &username_event_checkers) + | |
924 CreateScriptToRegisterListeners(kPasswordName, &password_event_checkers); | |
925 std::string html = std::string(kFormHTML) + events_registration_script; | |
923 LoadHTML(html.c_str()); | 926 LoadHTML(html.c_str()); |
924 UpdateOriginForHTML(html); | 927 UpdateOriginForHTML(html); |
925 UpdateUsernameAndPasswordElements(); | 928 UpdateUsernameAndPasswordElements(); |
926 | 929 |
927 // Simulate the browser sending back the login info, it triggers the | 930 // Simulate the browser sending back the login info, it triggers the |
928 // autocomplete. | 931 // autocomplete. |
929 SimulateOnFillPasswordForm(fill_data_); | 932 SimulateOnFillPasswordForm(fill_data_); |
930 | 933 |
931 // The username and password should have been autocompleted... | 934 // The username and password should have been autocompleted... |
932 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 935 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); |
933 // ... but since there hasn't been a user gesture yet, the autocompleted | 936 // ... but since there hasn't been a user gesture yet, the autocompleted |
934 // password should only be visible to the user. | 937 // password should only be visible to the user. |
935 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true); | 938 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true); |
936 | 939 |
937 // A JavaScript onChange event should have been triggered for the username, | 940 // A JavaScript events should have been triggered for the username, but not |
vabr (Chromium)
2017/03/21 07:57:30
nit: Remove "A": A JavaScript events -> JavaScript
kolos1
2017/03/21 08:29:21
Done.
| |
938 // but not yet for the password. | 941 // yet for the password. |
939 int username_onchange_called = -1; | 942 CheckIfEventsAreCalled(username_event_checkers, true); |
940 int password_onchange_called = -1; | 943 CheckIfEventsAreCalled(password_event_checkers, false); |
941 ASSERT_TRUE( | |
942 ExecuteJavaScriptAndReturnIntValue( | |
943 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), | |
944 &username_onchange_called)); | |
945 EXPECT_EQ(1, username_onchange_called); | |
946 ASSERT_TRUE( | |
947 ExecuteJavaScriptAndReturnIntValue( | |
948 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), | |
949 &password_onchange_called)); | |
950 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed. | |
951 // EXPECT_EQ(0, password_onchange_called); | |
952 | 944 |
953 // Simulate a user click so that the password field's real value is filled. | 945 // Simulate a user click so that the password field's real value is filled. |
954 SimulateElementClick(kUsernameName); | 946 SimulateElementClick(kUsernameName); |
955 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 947 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
956 | 948 |
957 // Now, a JavaScript onChange event should have been triggered for the | 949 // Now, JavaScript events should have been triggered for the password as well. |
958 // password as well. | 950 CheckIfEventsAreCalled(password_event_checkers, true); |
959 ASSERT_TRUE( | |
960 ExecuteJavaScriptAndReturnIntValue( | |
961 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), | |
962 &password_onchange_called)); | |
963 EXPECT_EQ(1, password_onchange_called); | |
964 } | 951 } |
965 | 952 |
966 // Verifies that password autofill triggers onChange events in JavaScript for | 953 // Verifies that password autofill triggers events in JavaScript for forms that |
967 // forms that are filled after page load. | 954 // are filled after page load. |
968 TEST_F(PasswordAutofillAgentTest, | 955 TEST_F(PasswordAutofillAgentTest, |
969 PasswordAutofillTriggersOnChangeEventsWaitForUsername) { | 956 PasswordAutofillTriggersOnChangeEventsWaitForUsername) { |
970 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript; | 957 std::vector<base::string16> event_checkers; |
958 std::string events_registration_script = | |
959 CreateScriptToRegisterListeners(kUsernameName, &event_checkers) + | |
960 CreateScriptToRegisterListeners(kPasswordName, &event_checkers); | |
961 std::string html = std::string(kFormHTML) + events_registration_script; | |
971 LoadHTML(html.c_str()); | 962 LoadHTML(html.c_str()); |
972 UpdateOriginForHTML(html); | 963 UpdateOriginForHTML(html); |
973 UpdateUsernameAndPasswordElements(); | 964 UpdateUsernameAndPasswordElements(); |
974 | 965 |
975 // Simulate the browser sending back the login info, it triggers the | 966 // Simulate the browser sending back the login info, it triggers the |
976 // autocomplete. | 967 // autocomplete. |
977 fill_data_.wait_for_username = true; | 968 fill_data_.wait_for_username = true; |
978 SimulateOnFillPasswordForm(fill_data_); | 969 SimulateOnFillPasswordForm(fill_data_); |
979 | 970 |
980 // The username and password should not yet have been autocompleted. | 971 // The username and password should not yet have been autocompleted. |
981 CheckTextFieldsState(std::string(), false, std::string(), false); | 972 CheckTextFieldsState(std::string(), false, std::string(), false); |
982 | 973 |
983 // Simulate a click just to force a user gesture, since the username value is | 974 // Simulate a click just to force a user gesture, since the username value is |
984 // set directly. | 975 // set directly. |
985 SimulateElementClick(kUsernameName); | 976 SimulateElementClick(kUsernameName); |
986 | 977 |
987 // Simulate the user entering the first letter of their username and selecting | 978 // Simulate the user entering the first letter of their username and selecting |
988 // the matching autofill from the dropdown. | 979 // the matching autofill from the dropdown. |
989 SimulateUsernameChange("a"); | 980 SimulateUsernameChange("a"); |
981 // Since the username element has focus, blur event will be not triggered. | |
982 base::Erase(event_checkers, base::ASCIIToUTF16("username_blur_event")); | |
990 SimulateSuggestionChoice(username_element_); | 983 SimulateSuggestionChoice(username_element_); |
991 | 984 |
992 // The username and password should now have been autocompleted. | 985 // The username and password should now have been autocompleted. |
993 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 986 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
994 | 987 |
995 // JavaScript onChange events should have been triggered both for the username | 988 // JavaScript events should have been triggered both for the username and for |
996 // and for the password. | 989 // the password. |
997 int username_onchange_called = -1; | 990 CheckIfEventsAreCalled(event_checkers, true); |
998 int password_onchange_called = -1; | |
999 ASSERT_TRUE( | |
1000 ExecuteJavaScriptAndReturnIntValue( | |
1001 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), | |
1002 &username_onchange_called)); | |
1003 EXPECT_EQ(1, username_onchange_called); | |
1004 ASSERT_TRUE( | |
1005 ExecuteJavaScriptAndReturnIntValue( | |
1006 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), | |
1007 &password_onchange_called)); | |
1008 EXPECT_EQ(1, password_onchange_called); | |
1009 } | 991 } |
1010 | 992 |
1011 // Tests that |FillSuggestion| properly fills the username and password. | 993 // Tests that |FillSuggestion| properly fills the username and password. |
1012 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { | 994 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { |
1013 // Simulate the browser sending the login info, but set |wait_for_username| | 995 // Simulate the browser sending the login info, but set |wait_for_username| |
1014 // to prevent the form from being immediately filled. | 996 // to prevent the form from being immediately filled. |
1015 fill_data_.wait_for_username = true; | 997 fill_data_.wait_for_username = true; |
1016 SimulateOnFillPasswordForm(fill_data_); | 998 SimulateOnFillPasswordForm(fill_data_); |
1017 | 999 |
1018 // Neither field should have been autocompleted. | 1000 // Neither field should have been autocompleted. |
(...skipping 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2590 SimulateElementClick(kUsernameName); | 2572 SimulateElementClick(kUsernameName); |
2591 | 2573 |
2592 // Simulate a user clicking on the password element. This should produce a | 2574 // Simulate a user clicking on the password element. This should produce a |
2593 // dropdown with suggestion of all available usernames. | 2575 // dropdown with suggestion of all available usernames. |
2594 static_cast<PageClickListener*>(autofill_agent_) | 2576 static_cast<PageClickListener*>(autofill_agent_) |
2595 ->FormControlElementClicked(password_element_, false); | 2577 ->FormControlElementClicked(password_element_, false); |
2596 CheckSuggestions("", false); | 2578 CheckSuggestions("", false); |
2597 } | 2579 } |
2598 | 2580 |
2599 } // namespace autofill | 2581 } // namespace autofill |
OLD | NEW |