| 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 password_element_ = element.to<blink::WebInputElement>(); | 254 password_element_ = element.to<blink::WebInputElement>(); |
| 255 } | 255 } |
| 256 | 256 |
| 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 SimulateDidEndEditingWithNoChangeForElement(WebFrame* input_frame, |
| 265 bool move_caret_to_end, | 265 WebInputElement& input) { |
| 266 WebFrame* input_frame, | 266 autofill_agent_->textFieldDidEndEditing(input); |
| 267 WebInputElement& username_input, | 267 } |
| 268 bool is_user_input) { | 268 |
| 269 username_input.setValue(WebString::fromUTF8(username), is_user_input); | 269 void SimulateInputChangeForElement(const std::string& new_value, |
| 270 bool move_caret_to_end, |
| 271 WebFrame* input_frame, |
| 272 WebInputElement& input, |
| 273 bool is_user_input) { |
| 274 input.setValue(WebString::fromUTF8(new_value), is_user_input); |
| 270 // The field must have focus or AutofillAgent will think the | 275 // The field must have focus or AutofillAgent will think the |
| 271 // change should be ignored. | 276 // change should be ignored. |
| 272 while (!username_input.focused()) | 277 while (!input.focused()) |
| 273 input_frame->document().frame()->view()->advanceFocus(false); | 278 input_frame->document().frame()->view()->advanceFocus(false); |
| 274 if (move_caret_to_end) | 279 if (move_caret_to_end) |
| 275 username_input.setSelectionRange(username.length(), username.length()); | 280 input.setSelectionRange(new_value.length(), new_value.length()); |
| 276 if (is_user_input) | 281 if (is_user_input) |
| 277 autofill_agent_->password_autofill_agent_->gatekeeper_.OnUserGesture(); | 282 autofill_agent_->password_autofill_agent_->FirstUserGestureObserved(); |
| 278 autofill_agent_->textFieldDidChange(username_input); | 283 autofill_agent_->textFieldDidChange(input); |
| 279 // Processing is delayed because of a Blink bug: | 284 // Processing is delayed because of a Blink bug: |
| 280 // https://bugs.webkit.org/show_bug.cgi?id=16976 | 285 // https://bugs.webkit.org/show_bug.cgi?id=16976 |
| 281 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. | 286 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. |
| 282 | 287 |
| 283 // Autocomplete will trigger a style recalculation when we put up the next | 288 // Autocomplete will trigger a style recalculation when we put up the next |
| 284 // frame, but we don't want to wait that long. Instead, trigger a style | 289 // frame, but we don't want to wait that long. Instead, trigger a style |
| 285 // recalcuation manually after TextFieldDidChangeImpl runs. | 290 // recalcuation manually after TextFieldDidChangeImpl runs. |
| 286 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 291 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 287 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); | 292 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); |
| 288 | 293 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 303 autofill_agent_->OnFillPasswordSuggestion(blink_username, blink_password); | 308 autofill_agent_->OnFillPasswordSuggestion(blink_username, blink_password); |
| 304 } | 309 } |
| 305 | 310 |
| 306 void LayoutMainFrame() { | 311 void LayoutMainFrame() { |
| 307 GetMainFrame()->view()->layout(); | 312 GetMainFrame()->view()->layout(); |
| 308 } | 313 } |
| 309 | 314 |
| 310 void SimulateUsernameChange(const std::string& username, | 315 void SimulateUsernameChange(const std::string& username, |
| 311 bool move_caret_to_end, | 316 bool move_caret_to_end, |
| 312 bool is_user_input = false) { | 317 bool is_user_input = false) { |
| 313 SimulateUsernameChangeForElement(username, | 318 SimulateInputChangeForElement(username, |
| 314 move_caret_to_end, | 319 move_caret_to_end, |
| 315 GetMainFrame(), | 320 GetMainFrame(), |
| 316 username_element_, | 321 username_element_, |
| 317 is_user_input); | 322 is_user_input); |
| 318 } | 323 } |
| 319 | 324 |
| 320 // Tests that no suggestion popup is generated when the username_element_ is | 325 // Tests that no suggestion popup is generated when the username_element_ is |
| 321 // edited. | 326 // edited. |
| 322 void ExpectNoSuggestionsPopup() { | 327 void ExpectNoSuggestionsPopup() { |
| 323 // The first test below ensures that the suggestions have been handled by | 328 // The first test below ensures that the suggestions have been handled by |
| 324 // the password_autofill_agent, even though autocomplete='off' is set. The | 329 // the password_autofill_agent, even though autocomplete='off' is set. The |
| 325 // second check ensures that, although handled, no "show suggestions" IPC to | 330 // second check ensures that, although handled, no "show suggestions" IPC to |
| 326 // the browser was generated. | 331 // the browser was generated. |
| 327 // | 332 // |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 | 902 |
| 898 WebInputElement username_input = username_element.to<WebInputElement>(); | 903 WebInputElement username_input = username_element.to<WebInputElement>(); |
| 899 WebInputElement password_input = password_element.to<WebInputElement>(); | 904 WebInputElement password_input = password_element.to<WebInputElement>(); |
| 900 ASSERT_FALSE(username_element.isNull()); | 905 ASSERT_FALSE(username_element.isNull()); |
| 901 | 906 |
| 902 CheckTextFieldsStateForElements( | 907 CheckTextFieldsStateForElements( |
| 903 username_input, "", false, password_input, "", false, false); | 908 username_input, "", false, password_input, "", false, false); |
| 904 | 909 |
| 905 // Simulate the user typing in the username in the iframe which should cause | 910 // Simulate the user typing in the username in the iframe which should cause |
| 906 // an autofill. | 911 // an autofill. |
| 907 SimulateUsernameChangeForElement( | 912 SimulateInputChangeForElement( |
| 908 kAliceUsername, true, iframe, username_input, true); | 913 kAliceUsername, true, iframe, username_input, true); |
| 909 | 914 |
| 910 CheckTextFieldsStateForElements(username_input, | 915 CheckTextFieldsStateForElements(username_input, |
| 911 kAliceUsername, | 916 kAliceUsername, |
| 912 true, | 917 true, |
| 913 password_input, | 918 password_input, |
| 914 kAlicePassword, | 919 kAlicePassword, |
| 915 true, | 920 true, |
| 916 false); | 921 false); |
| 917 } | 922 } |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 // Now simulate a user typing in the first letter of the username and then | 1472 // Now simulate a user typing in the first letter of the username and then |
| 1468 // clicking on the username element. While the typing of the first letter will | 1473 // clicking on the username element. While the typing of the first letter will |
| 1469 // inline autocomplete, clicking on the element should still produce a full | 1474 // inline autocomplete, clicking on the element should still produce a full |
| 1470 // suggestion list. | 1475 // suggestion list. |
| 1471 SimulateUsernameChange("a", true); | 1476 SimulateUsernameChange("a", true); |
| 1472 render_thread_->sink().ClearMessages(); | 1477 render_thread_->sink().ClearMessages(); |
| 1473 autofill_agent_->FormControlElementClicked(username_element_, true); | 1478 autofill_agent_->FormControlElementClicked(username_element_, true); |
| 1474 ExpectAllCredentials(); | 1479 ExpectAllCredentials(); |
| 1475 } | 1480 } |
| 1476 | 1481 |
| 1482 // The user first accepts a suggestion, but then overwrites the password. This |
| 1483 // test checks that the overwritten password is not reverted back by the user |
| 1484 // triggering autofill through focusing (but not changing) the username again. |
| 1485 TEST_F(PasswordAutofillAgentTest, PasswordNotOverwritten) { |
| 1486 // Simulate having credentials which needed to wait until the user starts |
| 1487 // typing the username to be filled (e.g., PSL-matched credentials). Those are |
| 1488 // the ones which can be filled as a result of TextFieldDidEndEditing. |
| 1489 fill_data_.wait_for_username = true; |
| 1490 // Simulate that the user typed her name to make the autofill work. |
| 1491 SimulateInputChangeForElement(kAliceUsername, |
| 1492 /*move_caret_to_end=*/true, |
| 1493 GetMainFrame(), |
| 1494 username_element_, |
| 1495 /*is_user_input=*/true); |
| 1496 SimulateOnFillPasswordForm(fill_data_); |
| 1497 |
| 1498 const std::string old_username(username_element_.value().utf8()); |
| 1499 const std::string old_password(password_element_.value().utf8()); |
| 1500 const std::string new_password(old_password + "modify"); |
| 1501 |
| 1502 // The user changes the password. |
| 1503 SimulateInputChangeForElement(new_password, |
| 1504 /*move_caret_to_end=*/true, |
| 1505 GetMainFrame(), |
| 1506 password_element_, |
| 1507 /*is_user_input=*/true); |
| 1508 |
| 1509 // The user switches back into the username field, but leaves that without |
| 1510 // changes. |
| 1511 SimulateDidEndEditingWithNoChangeForElement(GetMainFrame(), |
| 1512 username_element_); |
| 1513 |
| 1514 // The password should have stayed as the user changed it. |
| 1515 CheckTextFieldsDOMState(old_username, false, new_password, false); |
| 1516 // The password should not have a suggested value. |
| 1517 CheckTextFieldsState(old_username, false, std::string(), false); |
| 1518 } |
| 1519 |
| 1477 } // namespace autofill | 1520 } // namespace autofill |
| OLD | NEW |