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 |