Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: chrome/renderer/autofill/password_autofill_agent_browsertest.cc

Issue 166043006: Add password manager autocomplete suggestion when a username element in clicked. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on ToT Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 void ClearUsernameAndPasswordFields() { 257 void ClearUsernameAndPasswordFields() {
258 username_element_.setValue(""); 258 username_element_.setValue("");
259 username_element_.setAutofilled(false); 259 username_element_.setAutofilled(false);
260 password_element_.setValue(""); 260 password_element_.setValue("");
261 password_element_.setAutofilled(false); 261 password_element_.setAutofilled(false);
262 } 262 }
263 263
264 void SimulateUsernameChangeForElement(const std::string& username, 264 void SimulateUsernameChangeForElement(const std::string& username,
265 bool move_caret_to_end, 265 bool move_caret_to_end,
266 WebFrame* input_frame, 266 WebFrame* input_frame,
267 WebInputElement& username_input) { 267 WebInputElement& username_input,
268 username_input.setValue(WebString::fromUTF8(username)); 268 bool is_user_input) {
269 username_input.setValue(WebString::fromUTF8(username), is_user_input);
269 // The field must have focus or AutofillAgent will think the 270 // The field must have focus or AutofillAgent will think the
270 // change should be ignored. 271 // change should be ignored.
271 while (!username_input.focused()) 272 while (!username_input.focused())
272 input_frame->document().frame()->view()->advanceFocus(false); 273 input_frame->document().frame()->view()->advanceFocus(false);
273 if (move_caret_to_end) 274 if (move_caret_to_end)
274 username_input.setSelectionRange(username.length(), username.length()); 275 username_input.setSelectionRange(username.length(), username.length());
276 if (is_user_input)
277 autofill_agent_->password_autofill_agent_->gatekeeper_.OnUserGesture();
275 autofill_agent_->textFieldDidChange(username_input); 278 autofill_agent_->textFieldDidChange(username_input);
276 // Processing is delayed because of a Blink bug: 279 // Processing is delayed because of a Blink bug:
277 // https://bugs.webkit.org/show_bug.cgi?id=16976 280 // https://bugs.webkit.org/show_bug.cgi?id=16976
278 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. 281 // See PasswordAutofillAgent::TextDidChangeInTextField() for details.
279 282
280 // Autocomplete will trigger a style recalculation when we put up the next 283 // Autocomplete will trigger a style recalculation when we put up the next
281 // frame, but we don't want to wait that long. Instead, trigger a style 284 // frame, but we don't want to wait that long. Instead, trigger a style
282 // recalcuation manually after TextFieldDidChangeImpl runs. 285 // recalcuation manually after TextFieldDidChangeImpl runs.
283 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 286 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
284 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); 287 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this)));
285 288
286 base::MessageLoop::current()->RunUntilIdle(); 289 base::MessageLoop::current()->RunUntilIdle();
287 } 290 }
288 291
292 void SimulateSuggestionChoice(WebInputElement& username_input) {
293 blink::WebString blink_username =
294 blink::WebString::fromUTF8(kAliceUsername);
295 blink::WebString blink_password =
296 blink::WebString::fromUTF8(kAlicePassword);
297
298 // This call is necessary to setup the autofill agent appropriate for the
299 // user selection; simulates the menu actually popping up.
300 render_thread_->sink().ClearMessages();
301 autofill_agent_->FormControlElementClicked(username_input, false);
302
303 autofill_agent_->OnFillPasswordSuggestion(blink_username, blink_password);
304 }
305
289 void LayoutMainFrame() { 306 void LayoutMainFrame() {
290 GetMainFrame()->view()->layout(); 307 GetMainFrame()->view()->layout();
291 } 308 }
292 309
293 void SimulateUsernameChange(const std::string& username, 310 void SimulateUsernameChange(const std::string& username,
294 bool move_caret_to_end) { 311 bool move_caret_to_end,
295 SimulateUsernameChangeForElement(username, move_caret_to_end, 312 bool is_user_input = false) {
296 GetMainFrame(), username_element_); 313 SimulateUsernameChangeForElement(username,
314 move_caret_to_end,
315 GetMainFrame(),
316 username_element_,
317 is_user_input);
297 } 318 }
298 319
299 // Tests that no suggestion popup is generated when the username_element_ is 320 // Tests that no suggestion popup is generated when the username_element_ is
300 // edited. 321 // edited.
301 void ExpectNoSuggestionsPopup() { 322 void ExpectNoSuggestionsPopup() {
302 // The first test below ensures that the suggestions have been handled by 323 // The first test below ensures that the suggestions have been handled by
303 // the password_autofill_agent, even though autocomplete='off' is set. The 324 // the password_autofill_agent, even though autocomplete='off' is set. The
304 // second check ensures that, although handled, no "show suggestions" IPC to 325 // second check ensures that, although handled, no "show suggestions" IPC to
305 // the browser was generated. 326 // the browser was generated.
306 // 327 //
307 // This is interesting in the specific case of an autocomplete='off' form 328 // This is interesting in the specific case of an autocomplete='off' form
308 // that also has a remembered username and password 329 // that also has a remembered username and password
309 // (http://crbug.com/326679). To fix the DCHECK that this case used to hit, 330 // (http://crbug.com/326679). To fix the DCHECK that this case used to hit,
310 // |true| is returned from ShowSuggestions for all forms with valid 331 // |true| is returned from ShowSuggestions for all forms with valid
311 // usersnames that are autocomplete='off', prentending that a selection box 332 // usersnames that are autocomplete='off', prentending that a selection box
312 // has been shown to the user. Of course, it hasn't, so a message is never 333 // has been shown to the user. Of course, it hasn't, so a message is never
313 // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing 334 // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing
314 // is filled). 335 // is filled).
315 // 336 //
316 // These tests only make sense in the context of not ignoring 337 // These tests only make sense in the context of not ignoring
317 // autocomplete='off', so only test them if the disable autocomplete='off' 338 // autocomplete='off', so only test them if the disable autocomplete='off'
318 // flag is not enabled. 339 // flag is not enabled.
319 // TODO(jww): Remove this function and callers once autocomplete='off' is 340 // TODO(jww): Remove this function and callers once autocomplete='off' is
320 // permanently ignored. 341 // permanently ignored.
321 if (!ShouldIgnoreAutocompleteOffForPasswordFields()) { 342 if (!ShouldIgnoreAutocompleteOffForPasswordFields()) {
322 EXPECT_TRUE(autofill_agent_->password_autofill_agent_->ShowSuggestions( 343 EXPECT_TRUE(autofill_agent_->password_autofill_agent_->ShowSuggestions(
323 username_element_)); 344 username_element_, false));
324 345
325 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( 346 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
326 AutofillHostMsg_ShowPasswordSuggestions::ID)); 347 AutofillHostMsg_ShowPasswordSuggestions::ID));
327 } 348 }
328 } 349 }
329 350
330 void SimulateKeyDownEvent(const WebInputElement& element, 351 void SimulateKeyDownEvent(const WebInputElement& element,
331 ui::KeyboardCode key_code) { 352 ui::KeyboardCode key_code) {
332 blink::WebKeyboardEvent key_event; 353 blink::WebKeyboardEvent key_event;
333 key_event.windowsKeyCode = key_code; 354 key_event.windowsKeyCode = key_code;
334 autofill_agent_->textFieldDidReceiveKeyDown(element, key_event); 355 autofill_agent_->textFieldDidReceiveKeyDown(element, key_event);
335 } 356 }
336 357
337 void CheckTextFieldsStateForElements(const WebInputElement& username_element, 358 void CheckTextFieldsStateForElements(const WebInputElement& username_element,
338 const std::string& username, 359 const std::string& username,
339 bool username_autofilled, 360 bool username_autofilled,
340 const WebInputElement& password_element, 361 const WebInputElement& password_element,
341 const std::string& password, 362 const std::string& password,
342 bool password_autofilled, 363 bool password_autofilled,
343 bool checkSuggestedValue = true) { 364 bool checkSuggestedValue) {
344 EXPECT_EQ(username, 365 EXPECT_EQ(username,
345 static_cast<std::string>(username_element.value().utf8())); 366 static_cast<std::string>(username_element.value().utf8()));
346 EXPECT_EQ(username_autofilled, username_element.isAutofilled()); 367 EXPECT_EQ(username_autofilled, username_element.isAutofilled());
347 EXPECT_EQ(password, 368 EXPECT_EQ(password,
348 static_cast<std::string>( 369 static_cast<std::string>(
349 checkSuggestedValue ? password_element.suggestedValue().utf8() 370 checkSuggestedValue ? password_element.suggestedValue().utf8()
350 : password_element.value().utf8())); 371 : password_element.value().utf8()));
351 EXPECT_EQ(password_autofilled, password_element.isAutofilled()); 372 EXPECT_EQ(password_autofilled, password_element.isAutofilled());
352 } 373 }
353 374
354 // Checks the DOM-accessible value of the username element and the 375 // Checks the DOM-accessible value of the username element and the
355 // *suggested* value of the password element. 376 // *suggested* value of the password element.
356 void CheckTextFieldsState(const std::string& username, 377 void CheckTextFieldsState(const std::string& username,
357 bool username_autofilled, 378 bool username_autofilled,
358 const std::string& password, 379 const std::string& password,
359 bool password_autofilled) { 380 bool password_autofilled) {
360 CheckTextFieldsStateForElements(username_element_, username, 381 CheckTextFieldsStateForElements(username_element_,
361 username_autofilled, password_element_, 382 username,
362 password, password_autofilled); 383 username_autofilled,
384 password_element_,
385 password,
386 password_autofilled,
387 true);
363 } 388 }
364 389
365 // Checks the DOM-accessible value of the username element and the 390 // Checks the DOM-accessible value of the username element and the
366 // DOM-accessible value of the password element. 391 // DOM-accessible value of the password element.
367 void CheckTextFieldsDOMState(const std::string& username, 392 void CheckTextFieldsDOMState(const std::string& username,
368 bool username_autofilled, 393 bool username_autofilled,
369 const std::string& password, 394 const std::string& password,
370 bool password_autofilled) { 395 bool password_autofilled) {
371 CheckTextFieldsStateForElements(username_element_, 396 CheckTextFieldsStateForElements(username_element_,
372 username, 397 username,
373 username_autofilled, 398 username_autofilled,
374 password_element_, 399 password_element_,
375 password, 400 password,
376 password_autofilled, 401 password_autofilled,
377 false); 402 false);
378 } 403 }
379 404
380 void CheckUsernameSelection(int start, int end) { 405 void CheckUsernameSelection(int start, int end) {
381 EXPECT_EQ(start, username_element_.selectionStart()); 406 EXPECT_EQ(start, username_element_.selectionStart());
382 EXPECT_EQ(end, username_element_.selectionEnd()); 407 EXPECT_EQ(end, username_element_.selectionEnd());
383 } 408 }
384 409
410 void ExpectOneCredential(const base::string16& username) {
411 const IPC::Message* message =
412 render_thread_->sink().GetFirstMessageMatching(
413 AutofillHostMsg_ShowPasswordSuggestions::ID);
414 ASSERT_TRUE(message);
415 Tuple4<autofill::FormFieldData,
416 gfx::RectF,
417 std::vector<base::string16>,
418 std::vector<base::string16> > args;
419 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
420 ASSERT_EQ(1u, args.c.size());
421 EXPECT_TRUE(args.c[0] == username);
422 }
423
424 void ExpectAllCredentials() {
425 std::set<base::string16> usernames;
426 usernames.insert(username1_);
427 usernames.insert(username2_);
428 usernames.insert(username3_);
429 usernames.insert(alternate_username3_);
430
431 const IPC::Message* message =
432 render_thread_->sink().GetFirstMessageMatching(
433 AutofillHostMsg_ShowPasswordSuggestions::ID);
434 ASSERT_TRUE(message);
435 Tuple4<autofill::FormFieldData,
436 gfx::RectF,
437 std::vector<base::string16>,
438 std::vector<base::string16> > args;
439 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
440 ASSERT_EQ(4u, args.c.size());
441 std::set<base::string16>::iterator it;
442
443 for (int i = 0; i < 4; i++) {
444 it = usernames.find(args.c[i]);
445 EXPECT_TRUE(it != usernames.end());
446 if (it != usernames.end())
447 usernames.erase(it);
448 }
449
450 EXPECT_TRUE(usernames.empty());
451
452 render_thread_->sink().ClearMessages();
453 }
454
385 base::string16 username1_; 455 base::string16 username1_;
386 base::string16 username2_; 456 base::string16 username2_;
387 base::string16 username3_; 457 base::string16 username3_;
388 base::string16 password1_; 458 base::string16 password1_;
389 base::string16 password2_; 459 base::string16 password2_;
390 base::string16 password3_; 460 base::string16 password3_;
391 base::string16 alternate_username3_; 461 base::string16 alternate_username3_;
392 PasswordFormFillData fill_data_; 462 PasswordFormFillData fill_data_;
393 463
394 WebInputElement username_element_; 464 WebInputElement username_element_;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 username_element_.setValue(ASCIIToUTF16(kAliceUsername)); 715 username_element_.setValue(ASCIIToUTF16(kAliceUsername));
646 autofill_agent_->textFieldDidEndEditing(username_element_); 716 autofill_agent_->textFieldDidEndEditing(username_element_);
647 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); 717 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
648 } 718 }
649 719
650 // Tests that inline autocompletion works properly. 720 // Tests that inline autocompletion works properly.
651 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) { 721 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
652 // Simulate the browser sending back the login info. 722 // Simulate the browser sending back the login info.
653 SimulateOnFillPasswordForm(fill_data_); 723 SimulateOnFillPasswordForm(fill_data_);
654 724
655 // Clear the text fields to start fresh.
656 ClearUsernameAndPasswordFields(); 725 ClearUsernameAndPasswordFields();
657 726
658 // Simulate the user typing in the first letter of 'alice', a stored username. 727 // Simulate the user typing in the first letter of 'alice', a stored
728 // username.
659 SimulateUsernameChange("a", true); 729 SimulateUsernameChange("a", true);
660 // Both the username and password text fields should reflect selection of the 730 // Both the username and password text fields should reflect selection of the
661 // stored login. 731 // stored login.
662 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); 732 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
663 // And the selection should have been set to 'lice', the last 4 letters. 733 // And the selection should have been set to 'lice', the last 4 letters.
664 CheckUsernameSelection(1, 5); 734 CheckUsernameSelection(1, 5);
665 735
666 // Now the user types the next letter of the same username, 'l'. 736 // Now the user types the next letter of the same username, 'l'.
667 SimulateUsernameChange("al", true); 737 SimulateUsernameChange("al", true);
668 // Now the fields should have the same value, but the selection should have a 738 // 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
822 892
823 WebElement username_element = document.getElementById(kUsernameName); 893 WebElement username_element = document.getElementById(kUsernameName);
824 WebElement password_element = document.getElementById(kPasswordName); 894 WebElement password_element = document.getElementById(kPasswordName);
825 ASSERT_FALSE(username_element.isNull()); 895 ASSERT_FALSE(username_element.isNull());
826 ASSERT_FALSE(password_element.isNull()); 896 ASSERT_FALSE(password_element.isNull());
827 897
828 WebInputElement username_input = username_element.to<WebInputElement>(); 898 WebInputElement username_input = username_element.to<WebInputElement>();
829 WebInputElement password_input = password_element.to<WebInputElement>(); 899 WebInputElement password_input = password_element.to<WebInputElement>();
830 ASSERT_FALSE(username_element.isNull()); 900 ASSERT_FALSE(username_element.isNull());
831 901
832 CheckTextFieldsStateForElements(username_input, "", false, 902 CheckTextFieldsStateForElements(
833 password_input, "", false); 903 username_input, "", false, password_input, "", false, false);
834 904
835 // Simulate the user typing in the username in the iframe, which should cause 905 // Simulate the user typing in the username in the iframe which should cause
836 // an autofill. 906 // an autofill.
837 SimulateUsernameChangeForElement(kAliceUsername, true, 907 SimulateUsernameChangeForElement(
838 iframe, username_input); 908 kAliceUsername, true, iframe, username_input, true);
839 909
840 CheckTextFieldsStateForElements(username_input, kAliceUsername, true, 910 CheckTextFieldsStateForElements(username_input,
841 password_input, kAlicePassword, true); 911 kAliceUsername,
912 true,
913 password_input,
914 kAlicePassword,
915 true,
916 false);
842 } 917 }
843 918
844 // Tests that a password will only be filled as a suggested and will not be 919 // Tests that a password will only be filled as a suggested and will not be
845 // accessible by the DOM until a user gesture has occurred. 920 // accessible by the DOM until a user gesture has occurred.
846 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) { 921 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
847 // Trigger the initial autocomplete. 922 // Trigger the initial autocomplete.
848 SimulateOnFillPasswordForm(fill_data_); 923 SimulateOnFillPasswordForm(fill_data_);
849 924
850 // The username and password should have been autocompleted. 925 // The username and password should have been autocompleted.
851 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); 926 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 fill_data_.wait_for_username = true; 1068 fill_data_.wait_for_username = true;
994 SimulateOnFillPasswordForm(fill_data_); 1069 SimulateOnFillPasswordForm(fill_data_);
995 1070
996 // The username and password should not yet have been autocompleted. 1071 // The username and password should not yet have been autocompleted.
997 CheckTextFieldsState(std::string(), false, std::string(), false); 1072 CheckTextFieldsState(std::string(), false, std::string(), false);
998 1073
999 // Simulate a click just to force a user gesture, since the username value is 1074 // Simulate a click just to force a user gesture, since the username value is
1000 // set directly. 1075 // set directly.
1001 SimulateElementClick(kUsernameName); 1076 SimulateElementClick(kUsernameName);
1002 1077
1003 // Simulate the user entering her username. 1078 // Simulate the user entering her username and selecting the matching autofill
1004 username_element_.setValue(ASCIIToUTF16(kAliceUsername), true); 1079 // from the dropdown.
1005 autofill_agent_->textFieldDidEndEditing(username_element_); 1080 SimulateUsernameChange(kAliceUsername, true, true);
1081 SimulateSuggestionChoice(username_element_);
1006 1082
1007 // The username and password should now have been autocompleted. 1083 // The username and password should now have been autocompleted.
1008 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); 1084 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1009 1085
1010 // JavaScript onChange events should have been triggered both for the username 1086 // JavaScript onChange events should have been triggered both for the username
1011 // and for the password. 1087 // and for the password.
1012 int username_onchange_called = -1; 1088 int username_onchange_called = -1;
1013 int password_onchange_called = -1; 1089 int password_onchange_called = -1;
1014 ASSERT_TRUE( 1090 ASSERT_TRUE(
1015 ExecuteJavaScriptAndReturnIntValue( 1091 ExecuteJavaScriptAndReturnIntValue(
1016 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"), 1092 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
1017 &username_onchange_called)); 1093 &username_onchange_called));
1018 EXPECT_EQ(1, username_onchange_called); 1094 EXPECT_EQ(1, username_onchange_called);
1019 ASSERT_TRUE( 1095 ASSERT_TRUE(
1020 ExecuteJavaScriptAndReturnIntValue( 1096 ExecuteJavaScriptAndReturnIntValue(
1021 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"), 1097 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1022 &password_onchange_called)); 1098 &password_onchange_called));
1023 EXPECT_EQ(1, password_onchange_called); 1099 EXPECT_EQ(1, password_onchange_called); }
1024 }
1025 1100
1026 // Tests that |FillSuggestion| properly fills the username and password. 1101 // Tests that |FillSuggestion| properly fills the username and password.
1027 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { 1102 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
1028 // Simulate the browser sending the login info, but set |wait_for_username| 1103 // Simulate the browser sending the login info, but set |wait_for_username|
1029 // to prevent the form from being immediately filled. 1104 // to prevent the form from being immediately filled.
1030 fill_data_.wait_for_username = true; 1105 fill_data_.wait_for_username = true;
1031 SimulateOnFillPasswordForm(fill_data_); 1106 SimulateOnFillPasswordForm(fill_data_);
1032 1107
1033 // Neither field should have been autocompleted. 1108 // Neither field should have been autocompleted.
1034 CheckTextFieldsDOMState(std::string(), false, std::string(), false); 1109 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 } 1408 }
1334 1409
1335 // Test that the agent sends an IPC call to get the current activity state of 1410 // Test that the agent sends an IPC call to get the current activity state of
1336 // password saving logging soon after construction. 1411 // password saving logging soon after construction.
1337 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) { 1412 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1338 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching( 1413 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1339 AutofillHostMsg_PasswordAutofillAgentConstructed::ID); 1414 AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1340 EXPECT_TRUE(message); 1415 EXPECT_TRUE(message);
1341 } 1416 }
1342 1417
1418 // Tests that one user click on a username field is sufficient to bring up a
1419 // credential suggestion popup, and the user can autocomplete the password by
1420 // selecting the credential from the popup.
1421 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1422 // SimulateElementClick() is called so that a user gesture is actually made
1423 // and the password can be filled. However, SimulateElementClick() does not
1424 // actually lead to the AutofillAgent's InputElementClicked() method being
1425 // called, so SimulateSuggestionChoice has to manually call
1426 // InputElementClicked().
1427 ClearUsernameAndPasswordFields();
1428 SimulateOnFillPasswordForm(fill_data_);
1429 SimulateElementClick(kUsernameName);
1430 SimulateSuggestionChoice(username_element_);
1431 ExpectAllCredentials();
1432
1433 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1434 }
1435
1436 // Tests the autosuggestions that are given when the element is clicked.
1437 // Specifiaclly, tests when the user clicks on the username element after page
Garrett Casto 2014/07/15 22:17:19 Specifically
jww 2014/07/15 22:48:25 Done.
1438 // load and the element is autofilled, when the user clicks on an element that
1439 // has a non-matching username, and when the user clicks on an element that's
1440 // already been autofilled and they've already modified.
1441 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1442 // Simulate the browser sending back the login info.
1443 SimulateOnFillPasswordForm(fill_data_);
1444
1445 // Clear the text fields to start fresh.
1446 ClearUsernameAndPasswordFields();
1447
1448 // Call SimulateElementClick() to produce a user gesture on the page so
1449 // autofill will actually fill.
1450 SimulateElementClick(kUsernameName);
1451
1452 // Simulate a user clicking on the username element. This should produce a
1453 // message with all the usernames.
1454 render_thread_->sink().ClearMessages();
1455 autofill_agent_->FormControlElementClicked(username_element_, false);
1456 ExpectAllCredentials();
1457
1458 // Now simulate a user typing in an unrecognized username and then
1459 // clicking on the username element. This should also produce a message with
1460 // all the usernames.
1461 SimulateUsernameChange("baz", true);
1462 render_thread_->sink().ClearMessages();
1463 autofill_agent_->FormControlElementClicked(username_element_, true);
1464 ExpectAllCredentials();
1465
1466 // Now simulate a user typing in the first letter of the username and then
1467 // clicking on the username element. While the typing of the first letter will
1468 // inline autocomplete, clicking on the element should still produce a full
1469 // suggestion list.
1470 SimulateUsernameChange("a", true);
1471 render_thread_->sink().ClearMessages();
1472 autofill_agent_->FormControlElementClicked(username_element_, true);
1473 ExpectAllCredentials();
1474 }
1475
1343 } // namespace autofill 1476 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698