| 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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 void ClearUsernameAndPasswordFields() { | 247 void ClearUsernameAndPasswordFields() { |
| 248 username_element_.setValue(""); | 248 username_element_.setValue(""); |
| 249 username_element_.setAutofilled(false); | 249 username_element_.setAutofilled(false); |
| 250 password_element_.setValue(""); | 250 password_element_.setValue(""); |
| 251 password_element_.setAutofilled(false); | 251 password_element_.setAutofilled(false); |
| 252 } | 252 } |
| 253 | 253 |
| 254 void SimulateUsernameChangeForElement(const std::string& username, | 254 void SimulateUsernameChangeForElement(const std::string& username, |
| 255 bool move_caret_to_end, | 255 bool move_caret_to_end, |
| 256 WebFrame* input_frame, | 256 WebFrame* input_frame, |
| 257 WebInputElement& username_input) { | 257 WebInputElement& username_input, |
| 258 username_input.setValue(WebString::fromUTF8(username)); | 258 bool is_user_input) { |
| 259 username_input.setValue(WebString::fromUTF8(username), is_user_input); |
| 259 // The field must have focus or AutofillAgent will think the | 260 // The field must have focus or AutofillAgent will think the |
| 260 // change should be ignored. | 261 // change should be ignored. |
| 261 while (!username_input.focused()) | 262 while (!username_input.focused()) |
| 262 input_frame->document().frame()->view()->advanceFocus(false); | 263 input_frame->document().frame()->view()->advanceFocus(false); |
| 263 if (move_caret_to_end) | 264 if (move_caret_to_end) |
| 264 username_input.setSelectionRange(username.length(), username.length()); | 265 username_input.setSelectionRange(username.length(), username.length()); |
| 266 if (is_user_input) |
| 267 autofill_agent_->password_autofill_agent_->gatekeeper_.OnUserGesture(); |
| 265 autofill_agent_->textFieldDidChange(username_input); | 268 autofill_agent_->textFieldDidChange(username_input); |
| 266 // Processing is delayed because of a Blink bug: | 269 // Processing is delayed because of a Blink bug: |
| 267 // https://bugs.webkit.org/show_bug.cgi?id=16976 | 270 // https://bugs.webkit.org/show_bug.cgi?id=16976 |
| 268 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. | 271 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. |
| 269 | 272 |
| 270 // Autocomplete will trigger a style recalculation when we put up the next | 273 // Autocomplete will trigger a style recalculation when we put up the next |
| 271 // frame, but we don't want to wait that long. Instead, trigger a style | 274 // frame, but we don't want to wait that long. Instead, trigger a style |
| 272 // recalcuation manually after TextFieldDidChangeImpl runs. | 275 // recalcuation manually after TextFieldDidChangeImpl runs. |
| 273 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 276 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 274 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); | 277 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); |
| 275 | 278 |
| 276 base::MessageLoop::current()->RunUntilIdle(); | 279 base::MessageLoop::current()->RunUntilIdle(); |
| 277 } | 280 } |
| 278 | 281 |
| 282 void SimulateSuggestionChoice(const std::string& username, |
| 283 WebInputElement& username_input) { |
| 284 blink::WebString blink_username = blink::WebString::fromUTF8(username); |
| 285 |
| 286 // This call is necessary to setup the autofill agent appropriate for the |
| 287 // user selection; simulates the menu actually popping up. |
| 288 autofill_agent_->InputElementClicked(username_input, false, true); |
| 289 |
| 290 autofill_agent_->OnAcceptPasswordAutofillSuggestion(blink_username); |
| 291 } |
| 292 |
| 279 void LayoutMainFrame() { | 293 void LayoutMainFrame() { |
| 280 GetMainFrame()->view()->layout(); | 294 GetMainFrame()->view()->layout(); |
| 281 } | 295 } |
| 282 | 296 |
| 283 void SimulateUsernameChange(const std::string& username, | 297 void SimulateUsernameChange(const std::string& username, |
| 284 bool move_caret_to_end) { | 298 bool move_caret_to_end, |
| 285 SimulateUsernameChangeForElement(username, move_caret_to_end, | 299 bool is_user_input = false) { |
| 286 GetMainFrame(), username_element_); | 300 SimulateUsernameChangeForElement(username, |
| 301 move_caret_to_end, |
| 302 GetMainFrame(), |
| 303 username_element_, |
| 304 is_user_input); |
| 287 } | 305 } |
| 288 | 306 |
| 289 // Tests that no suggestion popup is generated when the username_element_ is | 307 // Tests that no suggestion popup is generated when the username_element_ is |
| 290 // edited. | 308 // edited. |
| 291 void ExpectNoSuggestionsPopup() { | 309 void ExpectNoSuggestionsPopup() { |
| 292 // The first test below ensures that the suggestions have been handled by | 310 // The first test below ensures that the suggestions have been handled by |
| 293 // the password_autofill_agent, even though autocomplete='off' is set. The | 311 // the password_autofill_agent, even though autocomplete='off' is set. The |
| 294 // second check ensures that, although handled, no "show suggestions" IPC to | 312 // second check ensures that, although handled, no "show suggestions" IPC to |
| 295 // the browser was generated. | 313 // the browser was generated. |
| 296 // | 314 // |
| 297 // This is interesting in the specific case of an autocomplete='off' form | 315 // This is interesting in the specific case of an autocomplete='off' form |
| 298 // that also has a remembered username and password | 316 // that also has a remembered username and password |
| 299 // (http://crbug.com/326679). To fix the DCHECK that this case used to hit, | 317 // (http://crbug.com/326679). To fix the DCHECK that this case used to hit, |
| 300 // |true| is returned from ShowSuggestions for all forms with valid | 318 // |true| is returned from ShowSuggestions for all forms with valid |
| 301 // usersnames that are autocomplete='off', prentending that a selection box | 319 // usersnames that are autocomplete='off', prentending that a selection box |
| 302 // has been shown to the user. Of course, it hasn't, so a message is never | 320 // has been shown to the user. Of course, it hasn't, so a message is never |
| 303 // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing | 321 // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing |
| 304 // is filled). | 322 // is filled). |
| 305 // | 323 // |
| 306 // These tests only make sense in the context of not ignoring | 324 // These tests only make sense in the context of not ignoring |
| 307 // autocomplete='off', so only test them if the disable autocomplete='off' | 325 // autocomplete='off', so only test them if the disable autocomplete='off' |
| 308 // flag is not enabled. | 326 // flag is not enabled. |
| 309 // TODO(jww): Remove this function and callers once autocomplete='off' is | 327 // TODO(jww): Remove this function and callers once autocomplete='off' is |
| 310 // permanently ignored. | 328 // permanently ignored. |
| 311 if (!ShouldIgnoreAutocompleteOffForPasswordFields()) { | 329 if (!ShouldIgnoreAutocompleteOffForPasswordFields()) { |
| 312 EXPECT_TRUE(autofill_agent_->password_autofill_agent_->ShowSuggestions( | 330 EXPECT_TRUE(autofill_agent_->password_autofill_agent_->ShowSuggestions( |
| 313 username_element_)); | 331 username_element_, false)); |
| 314 | 332 |
| 315 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( | 333 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( |
| 316 AutofillHostMsg_ShowPasswordSuggestions::ID)); | 334 AutofillHostMsg_ShowPasswordSuggestions::ID)); |
| 317 } | 335 } |
| 318 } | 336 } |
| 319 | 337 |
| 320 void SimulateKeyDownEvent(const WebInputElement& element, | 338 void SimulateKeyDownEvent(const WebInputElement& element, |
| 321 ui::KeyboardCode key_code) { | 339 ui::KeyboardCode key_code) { |
| 322 blink::WebKeyboardEvent key_event; | 340 blink::WebKeyboardEvent key_event; |
| 323 key_event.windowsKeyCode = key_code; | 341 key_event.windowsKeyCode = key_code; |
| 324 autofill_agent_->textFieldDidReceiveKeyDown(element, key_event); | 342 autofill_agent_->textFieldDidReceiveKeyDown(element, key_event); |
| 325 } | 343 } |
| 326 | 344 |
| 327 void CheckTextFieldsStateForElements(const WebInputElement& username_element, | 345 void CheckTextFieldsStateForElements(const WebInputElement& username_element, |
| 328 const std::string& username, | 346 const std::string& username, |
| 329 bool username_autofilled, | 347 bool username_autofilled, |
| 330 const WebInputElement& password_element, | 348 const WebInputElement& password_element, |
| 331 const std::string& password, | 349 const std::string& password, |
| 332 bool password_autofilled, | 350 bool password_autofilled, |
| 333 bool checkSuggestedValue = true) { | 351 bool checkSuggestedValue) { |
| 334 EXPECT_EQ(username, | 352 EXPECT_EQ(username, |
| 335 static_cast<std::string>(username_element.value().utf8())); | 353 static_cast<std::string>(username_element.value().utf8())); |
| 336 EXPECT_EQ(username_autofilled, username_element.isAutofilled()); | 354 EXPECT_EQ(username_autofilled, username_element.isAutofilled()); |
| 337 EXPECT_EQ(password, | 355 EXPECT_EQ(password, |
| 338 static_cast<std::string>( | 356 static_cast<std::string>( |
| 339 checkSuggestedValue ? password_element.suggestedValue().utf8() | 357 checkSuggestedValue ? password_element.suggestedValue().utf8() |
| 340 : password_element.value().utf8())); | 358 : password_element.value().utf8())); |
| 341 EXPECT_EQ(password_autofilled, password_element.isAutofilled()); | 359 EXPECT_EQ(password_autofilled, password_element.isAutofilled()); |
| 342 } | 360 } |
| 343 | 361 |
| 344 // Checks the DOM-accessible value of the username element and the | 362 // Checks the DOM-accessible value of the username element and the |
| 345 // *suggested* value of the password element. | 363 // *suggested* value of the password element. |
| 346 void CheckTextFieldsState(const std::string& username, | 364 void CheckTextFieldsState(const std::string& username, |
| 347 bool username_autofilled, | 365 bool username_autofilled, |
| 348 const std::string& password, | 366 const std::string& password, |
| 349 bool password_autofilled) { | 367 bool password_autofilled) { |
| 350 CheckTextFieldsStateForElements(username_element_, username, | 368 CheckTextFieldsStateForElements(username_element_, |
| 351 username_autofilled, password_element_, | 369 username, |
| 352 password, password_autofilled); | 370 username_autofilled, |
| 371 password_element_, |
| 372 password, |
| 373 password_autofilled, |
| 374 true); |
| 353 } | 375 } |
| 354 | 376 |
| 355 // Checks the DOM-accessible value of the username element and the | 377 // Checks the DOM-accessible value of the username element and the |
| 356 // DOM-accessible value of the password element. | 378 // DOM-accessible value of the password element. |
| 357 void CheckTextFieldsDOMState(const std::string& username, | 379 void CheckTextFieldsDOMState(const std::string& username, |
| 358 bool username_autofilled, | 380 bool username_autofilled, |
| 359 const std::string& password, | 381 const std::string& password, |
| 360 bool password_autofilled) { | 382 bool password_autofilled) { |
| 361 CheckTextFieldsStateForElements(username_element_, | 383 CheckTextFieldsStateForElements(username_element_, |
| 362 username, | 384 username, |
| 363 username_autofilled, | 385 username_autofilled, |
| 364 password_element_, | 386 password_element_, |
| 365 password, | 387 password, |
| 366 password_autofilled, | 388 password_autofilled, |
| 367 false); | 389 false); |
| 368 } | 390 } |
| 369 | 391 |
| 370 void CheckUsernameSelection(int start, int end) { | 392 void CheckUsernameSelection(int start, int end) { |
| 371 EXPECT_EQ(start, username_element_.selectionStart()); | 393 EXPECT_EQ(start, username_element_.selectionStart()); |
| 372 EXPECT_EQ(end, username_element_.selectionEnd()); | 394 EXPECT_EQ(end, username_element_.selectionEnd()); |
| 373 } | 395 } |
| 374 | 396 |
| 397 void ExpectOneCredential(const base::string16& username) { |
| 398 const IPC::Message* message = |
| 399 render_thread_->sink().GetFirstMessageMatching( |
| 400 AutofillHostMsg_ShowPasswordSuggestions::ID); |
| 401 ASSERT_TRUE(message); |
| 402 Tuple4<autofill::FormFieldData, |
| 403 gfx::RectF, |
| 404 std::vector<base::string16>, |
| 405 std::vector<base::string16> > args; |
| 406 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args); |
| 407 ASSERT_EQ(1u, args.c.size()); |
| 408 EXPECT_TRUE(args.c[0] == username); |
| 409 } |
| 410 |
| 411 void ExpectAllCredentials() { |
| 412 std::set<base::string16> usernames; |
| 413 usernames.insert(username1_); |
| 414 usernames.insert(username2_); |
| 415 usernames.insert(username3_); |
| 416 usernames.insert(alternate_username3_); |
| 417 |
| 418 const IPC::Message* message = |
| 419 render_thread_->sink().GetFirstMessageMatching( |
| 420 AutofillHostMsg_ShowPasswordSuggestions::ID); |
| 421 ASSERT_TRUE(message); |
| 422 Tuple4<autofill::FormFieldData, |
| 423 gfx::RectF, |
| 424 std::vector<base::string16>, |
| 425 std::vector<base::string16> > args; |
| 426 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args); |
| 427 ASSERT_EQ(4u, args.c.size()); |
| 428 std::set<base::string16>::iterator it; |
| 429 |
| 430 for (int i = 0; i < 4; i++) { |
| 431 it = usernames.find(args.c[i]); |
| 432 EXPECT_TRUE(it != usernames.end()); |
| 433 if (it != usernames.end()) |
| 434 usernames.erase(it); |
| 435 } |
| 436 |
| 437 EXPECT_TRUE(usernames.empty()); |
| 438 |
| 439 render_thread_->sink().ClearMessages(); |
| 440 } |
| 441 |
| 375 base::string16 username1_; | 442 base::string16 username1_; |
| 376 base::string16 username2_; | 443 base::string16 username2_; |
| 377 base::string16 username3_; | 444 base::string16 username3_; |
| 378 base::string16 password1_; | 445 base::string16 password1_; |
| 379 base::string16 password2_; | 446 base::string16 password2_; |
| 380 base::string16 password3_; | 447 base::string16 password3_; |
| 381 base::string16 alternate_username3_; | 448 base::string16 alternate_username3_; |
| 382 PasswordFormFillData fill_data_; | 449 PasswordFormFillData fill_data_; |
| 383 | 450 |
| 384 WebInputElement username_element_; | 451 WebInputElement username_element_; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 username_element_.setValue(ASCIIToUTF16(kAliceUsername)); | 705 username_element_.setValue(ASCIIToUTF16(kAliceUsername)); |
| 639 autofill_agent_->textFieldDidEndEditing(username_element_); | 706 autofill_agent_->textFieldDidEndEditing(username_element_); |
| 640 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 707 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); |
| 641 } | 708 } |
| 642 | 709 |
| 643 // Tests that inline autocompletion works properly. | 710 // Tests that inline autocompletion works properly. |
| 644 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) { | 711 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) { |
| 645 // Simulate the browser sending back the login info. | 712 // Simulate the browser sending back the login info. |
| 646 SimulateOnFillPasswordForm(fill_data_); | 713 SimulateOnFillPasswordForm(fill_data_); |
| 647 | 714 |
| 648 // Clear the text fields to start fresh. | |
| 649 ClearUsernameAndPasswordFields(); | 715 ClearUsernameAndPasswordFields(); |
| 650 | 716 |
| 651 // Simulate the user typing in the first letter of 'alice', a stored username. | 717 // Simulate the user typing in the first letter of 'alice', a stored |
| 718 // username. |
| 652 SimulateUsernameChange("a", true); | 719 SimulateUsernameChange("a", true); |
| 653 // Both the username and password text fields should reflect selection of the | 720 // Both the username and password text fields should reflect selection of the |
| 654 // stored login. | 721 // stored login. |
| 655 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 722 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); |
| 656 // And the selection should have been set to 'lice', the last 4 letters. | 723 // And the selection should have been set to 'lice', the last 4 letters. |
| 657 CheckUsernameSelection(1, 5); | 724 CheckUsernameSelection(1, 5); |
| 658 | 725 |
| 659 // Now the user types the next letter of the same username, 'l'. | 726 // Now the user types the next letter of the same username, 'l'. |
| 660 SimulateUsernameChange("al", true); | 727 SimulateUsernameChange("al", true); |
| 661 // Now the fields should have the same value, but the selection should have a | 728 // Now the fields should have the same value, but the selection should have a |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 | 882 |
| 816 WebElement username_element = document.getElementById(kUsernameName); | 883 WebElement username_element = document.getElementById(kUsernameName); |
| 817 WebElement password_element = document.getElementById(kPasswordName); | 884 WebElement password_element = document.getElementById(kPasswordName); |
| 818 ASSERT_FALSE(username_element.isNull()); | 885 ASSERT_FALSE(username_element.isNull()); |
| 819 ASSERT_FALSE(password_element.isNull()); | 886 ASSERT_FALSE(password_element.isNull()); |
| 820 | 887 |
| 821 WebInputElement username_input = username_element.to<WebInputElement>(); | 888 WebInputElement username_input = username_element.to<WebInputElement>(); |
| 822 WebInputElement password_input = password_element.to<WebInputElement>(); | 889 WebInputElement password_input = password_element.to<WebInputElement>(); |
| 823 ASSERT_FALSE(username_element.isNull()); | 890 ASSERT_FALSE(username_element.isNull()); |
| 824 | 891 |
| 825 CheckTextFieldsStateForElements(username_input, "", false, | 892 CheckTextFieldsStateForElements( |
| 826 password_input, "", false); | 893 username_input, "", false, password_input, "", false, false); |
| 827 | 894 |
| 828 // Simulate the user typing in the username in the iframe, which should cause | 895 // Simulate the user typing in the username in the iframe which should cause |
| 829 // an autofill. | 896 // an autofill. |
| 830 SimulateUsernameChangeForElement(kAliceUsername, true, | 897 SimulateUsernameChangeForElement( |
| 831 iframe, username_input); | 898 kAliceUsername, true, iframe, username_input, true); |
| 832 | 899 |
| 833 CheckTextFieldsStateForElements(username_input, kAliceUsername, true, | 900 CheckTextFieldsStateForElements(username_input, |
| 834 password_input, kAlicePassword, true); | 901 kAliceUsername, |
| 902 true, |
| 903 password_input, |
| 904 kAlicePassword, |
| 905 true, |
| 906 false); |
| 835 } | 907 } |
| 836 | 908 |
| 837 // Tests that a password will only be filled as a suggested and will not be | 909 // Tests that a password will only be filled as a suggested and will not be |
| 838 // accessible by the DOM until a user gesture has occurred. | 910 // accessible by the DOM until a user gesture has occurred. |
| 839 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) { | 911 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) { |
| 840 // Trigger the initial autocomplete. | 912 // Trigger the initial autocomplete. |
| 841 SimulateOnFillPasswordForm(fill_data_); | 913 SimulateOnFillPasswordForm(fill_data_); |
| 842 | 914 |
| 843 // The username and password should have been autocompleted. | 915 // The username and password should have been autocompleted. |
| 844 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 916 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 fill_data_.wait_for_username = true; | 1058 fill_data_.wait_for_username = true; |
| 987 SimulateOnFillPasswordForm(fill_data_); | 1059 SimulateOnFillPasswordForm(fill_data_); |
| 988 | 1060 |
| 989 // The username and password should not yet have been autocompleted. | 1061 // The username and password should not yet have been autocompleted. |
| 990 CheckTextFieldsState(std::string(), false, std::string(), false); | 1062 CheckTextFieldsState(std::string(), false, std::string(), false); |
| 991 | 1063 |
| 992 // Simulate a click just to force a user gesture, since the username value is | 1064 // Simulate a click just to force a user gesture, since the username value is |
| 993 // set directly. | 1065 // set directly. |
| 994 SimulateElementClick(kUsernameName); | 1066 SimulateElementClick(kUsernameName); |
| 995 | 1067 |
| 996 // Simulate the user entering her username. | 1068 // Simulate the user entering her username and selecting the matching autofill |
| 997 username_element_.setValue(ASCIIToUTF16(kAliceUsername), true); | 1069 // from the dropdown. |
| 998 autofill_agent_->textFieldDidEndEditing(username_element_); | 1070 SimulateUsernameChange(kAliceUsername, true, true); |
| 1071 SimulateSuggestionChoice(kAliceUsername, username_element_); |
| 999 | 1072 |
| 1000 // The username and password should now have been autocompleted. | 1073 // The username and password should now have been autocompleted. |
| 1001 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 1074 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
| 1002 | 1075 |
| 1003 // JavaScript onChange events should have been triggered both for the username | 1076 // JavaScript onChange events should have been triggered both for the username |
| 1004 // and for the password. | 1077 // and for the password. |
| 1005 int username_onchange_called = -1; | 1078 int username_onchange_called = -1; |
| 1006 int password_onchange_called = -1; | 1079 int password_onchange_called = -1; |
| 1007 ASSERT_TRUE( | 1080 ASSERT_TRUE( |
| 1008 ExecuteJavaScriptAndReturnIntValue( | 1081 ExecuteJavaScriptAndReturnIntValue( |
| 1009 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), | 1082 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), |
| 1010 &username_onchange_called)); | 1083 &username_onchange_called)); |
| 1011 EXPECT_EQ(1, username_onchange_called); | 1084 EXPECT_EQ(1, username_onchange_called); |
| 1012 ASSERT_TRUE( | 1085 ASSERT_TRUE( |
| 1013 ExecuteJavaScriptAndReturnIntValue( | 1086 ExecuteJavaScriptAndReturnIntValue( |
| 1014 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), | 1087 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), |
| 1015 &password_onchange_called)); | 1088 &password_onchange_called)); |
| 1016 EXPECT_EQ(1, password_onchange_called); | 1089 EXPECT_EQ(1, password_onchange_called); |
| 1017 } | 1090 } |
| 1018 | 1091 |
| 1092 // Tests that one user click on a username field is sufficient to bring up a |
| 1093 // credential suggestion popup, and the user can autocomplete the password by |
| 1094 // selecting the credential from the popup. |
| 1095 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) { |
| 1096 // Simulate the browser sending back the login info. |
| 1097 SimulateOnFillPasswordForm(fill_data_); |
| 1098 |
| 1099 // Clear the text fields to start fresh. |
| 1100 ClearUsernameAndPasswordFields(); |
| 1101 |
| 1102 // SimulateElementClick() is called so that a user gesture is actually made |
| 1103 // and the password can be filled. However, SimulateElementClick() does not |
| 1104 // actually lead to the AutofillAgent's InputElementClicked() method being |
| 1105 // called, so SimulateSuggestionChoice has to manually call |
| 1106 // InputElementClicked(). |
| 1107 SimulateElementClick(kUsernameName); |
| 1108 SimulateSuggestionChoice(kAliceUsername, username_element_); |
| 1109 |
| 1110 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
| 1111 } |
| 1112 |
| 1113 // Tests the autosuggestions that are given when the element is clicked. |
| 1114 // Specifiaclly, tests when the user clicks on the username element after page |
| 1115 // load and the element is autofilled, when the user clicks on an element that |
| 1116 // has a non-matching username, and when the user clicks on an element that's |
| 1117 // already been autofilled and they've already modified. |
| 1118 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) { |
| 1119 // Simulate the browser sending back the login info. |
| 1120 SimulateOnFillPasswordForm(fill_data_); |
| 1121 |
| 1122 // Clear the text fields to start fresh. |
| 1123 ClearUsernameAndPasswordFields(); |
| 1124 |
| 1125 // Call SimulateElementClick() to produce a user gesture on the page so |
| 1126 // autofill will actually fill. |
| 1127 SimulateElementClick(kUsernameName); |
| 1128 |
| 1129 // Simulate a user clicking on the username element. This should produce a |
| 1130 // message with all the usernames. |
| 1131 render_thread_->sink().ClearMessages(); |
| 1132 autofill_agent_->InputElementClicked(username_element_, false, true); |
| 1133 ExpectAllCredentials(); |
| 1134 |
| 1135 // Now simulate a user typing in an unrecognized username and then |
| 1136 // clicking on the username element. This should also produce a message with |
| 1137 // all the usernames. |
| 1138 SimulateUsernameChange("baz", true); |
| 1139 render_thread_->sink().ClearMessages(); |
| 1140 autofill_agent_->InputElementClicked(username_element_, true, true); |
| 1141 ExpectAllCredentials(); |
| 1142 |
| 1143 // Now simulate a user typing in the first letter of the username and then |
| 1144 // clicking on the username element. While the typing of the first letter will |
| 1145 // inline autocomplete, clicking on the element should produce a message just |
| 1146 // the one username. |
| 1147 SimulateUsernameChange("a", true); |
| 1148 render_thread_->sink().ClearMessages(); |
| 1149 autofill_agent_->InputElementClicked(username_element_, true, true); |
| 1150 ExpectOneCredential(username1_); |
| 1151 } |
| 1152 |
| 1019 } // namespace autofill | 1153 } // namespace autofill |
| OLD | NEW |