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<std::string> checkers, | |
vabr (Chromium)
2017/03/17 12:01:06
Please pass the vector by (const) reference, not b
kolos1
2017/03/17 12:47:36
Done.
| |
543 bool expected) { | |
544 for (const std::string& variable : checkers) { | |
545 int value; | |
546 EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue( | |
547 base::UTF8ToUTF16(variable), &value)) | |
548 << variable; | |
549 EXPECT_EQ(expected, value == 1) << variable; | |
550 } | |
551 } | |
552 | |
554 bool GetCalledShowPasswordGenerationPopup() { | 553 bool GetCalledShowPasswordGenerationPopup() { |
555 fake_pw_client_.Flush(); | 554 fake_pw_client_.Flush(); |
556 return fake_pw_client_.called_show_pw_generation_popup(); | 555 return fake_pw_client_.called_show_pw_generation_popup(); |
557 } | 556 } |
558 | 557 |
559 void BindPasswordManagerDriver(mojo::ScopedMessagePipeHandle handle) { | 558 void BindPasswordManagerDriver(mojo::ScopedMessagePipeHandle handle) { |
560 fake_driver_.BindRequest( | 559 fake_driver_.BindRequest( |
561 mojo::MakeRequest<mojom::PasswordManagerDriver>(std::move(handle))); | 560 mojo::MakeRequest<mojom::PasswordManagerDriver>(std::move(handle))); |
562 } | 561 } |
563 | 562 |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
912 SimulateOnFillPasswordForm(fill_data_); | 911 SimulateOnFillPasswordForm(fill_data_); |
913 | 912 |
914 ExecuteJavaScriptForTests(kJavaScriptClick); | 913 ExecuteJavaScriptForTests(kJavaScriptClick); |
915 CheckTextFieldsDOMState(kAliceUsername, true, "", true); | 914 CheckTextFieldsDOMState(kAliceUsername, true, "", true); |
916 } | 915 } |
917 | 916 |
918 // Verifies that password autofill triggers onChange events in JavaScript for | 917 // Verifies that password autofill triggers onChange events in JavaScript for |
919 // forms that are filled on page load. | 918 // forms that are filled on page load. |
920 TEST_F(PasswordAutofillAgentTest, | 919 TEST_F(PasswordAutofillAgentTest, |
921 PasswordAutofillTriggersOnChangeEventsOnLoad) { | 920 PasswordAutofillTriggersOnChangeEventsOnLoad) { |
922 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript; | 921 std::string html = std::string(kFormHTML); |
923 LoadHTML(html.c_str()); | 922 LoadHTML(html.c_str()); |
924 UpdateOriginForHTML(html); | 923 UpdateOriginForHTML(html); |
925 UpdateUsernameAndPasswordElements(); | 924 UpdateUsernameAndPasswordElements(); |
926 | 925 |
926 std::vector<std::string> username_event_checkers; | |
927 std::vector<std::string> password_event_checkers; | |
928 std::string events_registration_script = | |
929 CreateScriptToRegisterListeners(kUsernameName, &username_event_checkers) + | |
930 CreateScriptToRegisterListeners(kPasswordName, &password_event_checkers); | |
931 ExecuteJavaScriptForTests(events_registration_script.c_str()); | |
932 | |
927 // Simulate the browser sending back the login info, it triggers the | 933 // Simulate the browser sending back the login info, it triggers the |
928 // autocomplete. | 934 // autocomplete. |
929 SimulateOnFillPasswordForm(fill_data_); | 935 SimulateOnFillPasswordForm(fill_data_); |
930 | 936 |
931 // The username and password should have been autocompleted... | 937 // The username and password should have been autocompleted... |
932 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 938 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); |
933 // ... but since there hasn't been a user gesture yet, the autocompleted | 939 // ... but since there hasn't been a user gesture yet, the autocompleted |
934 // password should only be visible to the user. | 940 // password should only be visible to the user. |
935 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true); | 941 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true); |
936 | 942 |
937 // A JavaScript onChange event should have been triggered for the username, | 943 // A JavaScript onChange event should have been triggered for the username, |
938 // but not yet for the password. | 944 // but not yet for the password. |
939 int username_onchange_called = -1; | 945 |
940 int password_onchange_called = -1; | 946 CheckIfEventsAreCalled(username_event_checkers, true); |
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. | 947 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed. |
vabr (Chromium)
2017/03/17 12:01:07
This comment looks obsoleted by your changes.
kolos1
2017/03/17 12:47:36
Done.
| |
951 // EXPECT_EQ(0, password_onchange_called); | 948 CheckIfEventsAreCalled(password_event_checkers, false); |
952 | 949 |
953 // Simulate a user click so that the password field's real value is filled. | 950 // Simulate a user click so that the password field's real value is filled. |
954 SimulateElementClick(kUsernameName); | 951 SimulateElementClick(kUsernameName); |
955 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 952 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
956 | 953 |
957 // Now, a JavaScript onChange event should have been triggered for the | 954 // Now, a JavaScript onChange event should have been triggered for the |
958 // password as well. | 955 // password as well. |
959 ASSERT_TRUE( | 956 CheckIfEventsAreCalled(password_event_checkers, true); |
960 ExecuteJavaScriptAndReturnIntValue( | |
961 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), | |
962 &password_onchange_called)); | |
963 EXPECT_EQ(1, password_onchange_called); | |
964 } | 957 } |
965 | 958 |
966 // Verifies that password autofill triggers onChange events in JavaScript for | 959 // Verifies that password autofill triggers onChange events in JavaScript for |
967 // forms that are filled after page load. | 960 // forms that are filled after page load. |
968 TEST_F(PasswordAutofillAgentTest, | 961 TEST_F(PasswordAutofillAgentTest, |
969 PasswordAutofillTriggersOnChangeEventsWaitForUsername) { | 962 PasswordAutofillTriggersOnChangeEventsWaitForUsername) { |
970 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript; | 963 std::string html = std::string(kFormHTML); |
971 LoadHTML(html.c_str()); | 964 LoadHTML(html.c_str()); |
972 UpdateOriginForHTML(html); | 965 UpdateOriginForHTML(html); |
973 UpdateUsernameAndPasswordElements(); | 966 UpdateUsernameAndPasswordElements(); |
974 | 967 |
968 std::vector<std::string> event_checkers; | |
969 std::string events_registration_script = | |
970 CreateScriptToRegisterListeners(kUsernameName, &event_checkers) + | |
971 CreateScriptToRegisterListeners(kPasswordName, &event_checkers); | |
972 ExecuteJavaScriptForTests(events_registration_script.c_str()); | |
973 | |
975 // Simulate the browser sending back the login info, it triggers the | 974 // Simulate the browser sending back the login info, it triggers the |
976 // autocomplete. | 975 // autocomplete. |
977 fill_data_.wait_for_username = true; | 976 fill_data_.wait_for_username = true; |
978 SimulateOnFillPasswordForm(fill_data_); | 977 SimulateOnFillPasswordForm(fill_data_); |
979 | 978 |
980 // The username and password should not yet have been autocompleted. | 979 // The username and password should not yet have been autocompleted. |
981 CheckTextFieldsState(std::string(), false, std::string(), false); | 980 CheckTextFieldsState(std::string(), false, std::string(), false); |
982 | 981 |
983 // Simulate a click just to force a user gesture, since the username value is | 982 // Simulate a click just to force a user gesture, since the username value is |
984 // set directly. | 983 // set directly. |
985 SimulateElementClick(kUsernameName); | 984 SimulateElementClick(kUsernameName); |
986 | 985 |
987 // Simulate the user entering the first letter of their username and selecting | 986 // Simulate the user entering the first letter of their username and selecting |
988 // the matching autofill from the dropdown. | 987 // the matching autofill from the dropdown. |
989 SimulateUsernameChange("a"); | 988 SimulateUsernameChange("a"); |
989 // Since the username element has focus, blur event will ne be triggered. | |
990 event_checkers.erase(std::remove(event_checkers.begin(), event_checkers.end(), | |
vabr (Chromium)
2017/03/17 12:01:06
Please use base::Erase instead (this is a recent c
kolos1
2017/03/17 12:47:36
Done.
| |
991 "username_blur_event"), | |
992 event_checkers.end()); | |
990 SimulateSuggestionChoice(username_element_); | 993 SimulateSuggestionChoice(username_element_); |
991 | 994 |
992 // The username and password should now have been autocompleted. | 995 // The username and password should now have been autocompleted. |
993 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 996 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
994 | 997 |
995 // JavaScript onChange events should have been triggered both for the username | 998 // JavaScript onChange events should have been triggered both for the username |
996 // and for the password. | 999 // and for the password. |
997 int username_onchange_called = -1; | 1000 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 } | 1001 } |
1010 | 1002 |
1011 // Tests that |FillSuggestion| properly fills the username and password. | 1003 // Tests that |FillSuggestion| properly fills the username and password. |
1012 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { | 1004 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { |
1013 // Simulate the browser sending the login info, but set |wait_for_username| | 1005 // Simulate the browser sending the login info, but set |wait_for_username| |
1014 // to prevent the form from being immediately filled. | 1006 // to prevent the form from being immediately filled. |
1015 fill_data_.wait_for_username = true; | 1007 fill_data_.wait_for_username = true; |
1016 SimulateOnFillPasswordForm(fill_data_); | 1008 SimulateOnFillPasswordForm(fill_data_); |
1017 | 1009 |
1018 // Neither field should have been autocompleted. | 1010 // Neither field should have been autocompleted. |
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2531 SimulateElementClick(kUsernameName); | 2523 SimulateElementClick(kUsernameName); |
2532 | 2524 |
2533 // Simulate a user clicking on the password element. This should produce a | 2525 // Simulate a user clicking on the password element. This should produce a |
2534 // dropdown with suggestion of all available usernames. | 2526 // dropdown with suggestion of all available usernames. |
2535 static_cast<PageClickListener*>(autofill_agent_) | 2527 static_cast<PageClickListener*>(autofill_agent_) |
2536 ->FormControlElementClicked(password_element_, false); | 2528 ->FormControlElementClicked(password_element_, false); |
2537 CheckSuggestions("", false); | 2529 CheckSuggestions("", false); |
2538 } | 2530 } |
2539 | 2531 |
2540 } // namespace autofill | 2532 } // namespace autofill |
OLD | NEW |