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 SimulateDidEndEditing(WebFrame* input_frame, WebInputElement& input) { |
265 bool move_caret_to_end, | 265 autofill_agent_->textFieldDidEndEditing(input); |
266 WebFrame* input_frame, | 266 } |
267 WebInputElement& username_input, | 267 |
268 bool is_user_input) { | 268 void SimulateInputChangeForElement(const std::string& new_value, |
269 username_input.setValue(WebString::fromUTF8(username), is_user_input); | 269 bool move_caret_to_end, |
270 WebFrame* input_frame, | |
271 WebInputElement& input, | |
272 bool is_user_input) { | |
273 input.setValue(WebString::fromUTF8(new_value), is_user_input); | |
270 // The field must have focus or AutofillAgent will think the | 274 // The field must have focus or AutofillAgent will think the |
271 // change should be ignored. | 275 // change should be ignored. |
272 while (!username_input.focused()) | 276 while (!input.focused()) |
273 input_frame->document().frame()->view()->advanceFocus(false); | 277 input_frame->document().frame()->view()->advanceFocus(false); |
274 if (move_caret_to_end) | 278 if (move_caret_to_end) |
275 username_input.setSelectionRange(username.length(), username.length()); | 279 input.setSelectionRange(new_value.length(), new_value.length()); |
276 if (is_user_input) | 280 if (is_user_input) |
277 password_autofill_agent()->FirstUserGestureObserved(); | 281 password_autofill_agent()->FirstUserGestureObserved(); |
278 autofill_agent_->textFieldDidChange(username_input); | 282 autofill_agent_->textFieldDidChange(input); |
279 // Processing is delayed because of a Blink bug: | 283 // Processing is delayed because of a Blink bug: |
280 // https://bugs.webkit.org/show_bug.cgi?id=16976 | 284 // https://bugs.webkit.org/show_bug.cgi?id=16976 |
281 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. | 285 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. |
282 | 286 |
283 // Autocomplete will trigger a style recalculation when we put up the next | 287 // 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 | 288 // frame, but we don't want to wait that long. Instead, trigger a style |
285 // recalcuation manually after TextFieldDidChangeImpl runs. | 289 // recalcuation manually after TextFieldDidChangeImpl runs. |
286 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 290 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
287 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); | 291 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); |
288 | 292 |
(...skipping 14 matching lines...) Expand all Loading... | |
303 autofill_agent_->OnFillPasswordSuggestion(blink_username, blink_password); | 307 autofill_agent_->OnFillPasswordSuggestion(blink_username, blink_password); |
304 } | 308 } |
305 | 309 |
306 void LayoutMainFrame() { | 310 void LayoutMainFrame() { |
307 GetMainFrame()->view()->layout(); | 311 GetMainFrame()->view()->layout(); |
308 } | 312 } |
309 | 313 |
310 void SimulateUsernameChange(const std::string& username, | 314 void SimulateUsernameChange(const std::string& username, |
311 bool move_caret_to_end, | 315 bool move_caret_to_end, |
312 bool is_user_input = false) { | 316 bool is_user_input = false) { |
313 SimulateUsernameChangeForElement(username, | 317 SimulateInputChangeForElement(username, |
314 move_caret_to_end, | 318 move_caret_to_end, |
315 GetMainFrame(), | 319 GetMainFrame(), |
316 username_element_, | 320 username_element_, |
317 is_user_input); | 321 is_user_input); |
318 } | 322 } |
319 | 323 |
320 // Tests that no suggestion popup is generated when the username_element_ is | 324 // Tests that no suggestion popup is generated when the username_element_ is |
321 // edited. | 325 // edited. |
322 void ExpectNoSuggestionsPopup() { | 326 void ExpectNoSuggestionsPopup() { |
323 // The first test below ensures that the suggestions have been handled by | 327 // The first test below ensures that the suggestions have been handled by |
324 // the password_autofill_agent, even though autocomplete='off' is set. The | 328 // the password_autofill_agent, even though autocomplete='off' is set. The |
325 // second check ensures that, although handled, no "show suggestions" IPC to | 329 // second check ensures that, although handled, no "show suggestions" IPC to |
326 // the browser was generated. | 330 // the browser was generated. |
327 // | 331 // |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 const WebInputElement& password_element, | 365 const WebInputElement& password_element, |
362 const std::string& password, | 366 const std::string& password, |
363 bool password_autofilled, | 367 bool password_autofilled, |
364 bool checkSuggestedValue) { | 368 bool checkSuggestedValue) { |
365 EXPECT_EQ(username, | 369 EXPECT_EQ(username, |
366 static_cast<std::string>(username_element.value().utf8())); | 370 static_cast<std::string>(username_element.value().utf8())); |
367 EXPECT_EQ(username_autofilled, username_element.isAutofilled()); | 371 EXPECT_EQ(username_autofilled, username_element.isAutofilled()); |
368 EXPECT_EQ(password, | 372 EXPECT_EQ(password, |
369 static_cast<std::string>( | 373 static_cast<std::string>( |
370 checkSuggestedValue ? password_element.suggestedValue().utf8() | 374 checkSuggestedValue ? password_element.suggestedValue().utf8() |
371 : password_element.value().utf8())); | 375 : password_element.value().utf8())) |
376 << "checkSuggestedValue == " << checkSuggestedValue; | |
372 EXPECT_EQ(password_autofilled, password_element.isAutofilled()); | 377 EXPECT_EQ(password_autofilled, password_element.isAutofilled()); |
373 } | 378 } |
374 | 379 |
375 // Checks the DOM-accessible value of the username element and the | 380 // Checks the DOM-accessible value of the username element and the |
376 // *suggested* value of the password element. | 381 // *suggested* value of the password element. |
377 void CheckTextFieldsState(const std::string& username, | 382 void CheckTextFieldsState(const std::string& username, |
378 bool username_autofilled, | 383 bool username_autofilled, |
379 const std::string& password, | 384 const std::string& password, |
380 bool password_autofilled) { | 385 bool password_autofilled) { |
381 CheckTextFieldsStateForElements(username_element_, | 386 CheckTextFieldsStateForElements(username_element_, |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
913 | 918 |
914 WebInputElement username_input = username_element.to<WebInputElement>(); | 919 WebInputElement username_input = username_element.to<WebInputElement>(); |
915 WebInputElement password_input = password_element.to<WebInputElement>(); | 920 WebInputElement password_input = password_element.to<WebInputElement>(); |
916 ASSERT_FALSE(username_element.isNull()); | 921 ASSERT_FALSE(username_element.isNull()); |
917 | 922 |
918 CheckTextFieldsStateForElements( | 923 CheckTextFieldsStateForElements( |
919 username_input, "", false, password_input, "", false, false); | 924 username_input, "", false, password_input, "", false, false); |
920 | 925 |
921 // Simulate the user typing in the username in the iframe which should cause | 926 // Simulate the user typing in the username in the iframe which should cause |
922 // an autofill. | 927 // an autofill. |
923 SimulateUsernameChangeForElement( | 928 SimulateInputChangeForElement( |
924 kAliceUsername, true, iframe, username_input, true); | 929 kAliceUsername, true, iframe, username_input, true); |
925 | 930 |
926 CheckTextFieldsStateForElements(username_input, | 931 CheckTextFieldsStateForElements(username_input, |
927 kAliceUsername, | 932 kAliceUsername, |
928 true, | 933 true, |
929 password_input, | 934 password_input, |
930 kAlicePassword, | 935 kAlicePassword, |
931 true, | 936 true, |
932 false); | 937 false); |
933 } | 938 } |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 render_thread_->sink().ClearMessages(); | 1493 render_thread_->sink().ClearMessages(); |
1489 autofill_agent_->FormControlElementClicked(username_element_, true); | 1494 autofill_agent_->FormControlElementClicked(username_element_, true); |
1490 ExpectAllCredentials(); | 1495 ExpectAllCredentials(); |
1491 } | 1496 } |
1492 | 1497 |
1493 // The user types in a password, but then just before sending the form off, a | 1498 // The user types in a password, but then just before sending the form off, a |
1494 // script clears that password. This test checks that PasswordAutofillAgent can | 1499 // script clears that password. This test checks that PasswordAutofillAgent can |
1495 // still remember the password typed by the user. | 1500 // still remember the password typed by the user. |
1496 TEST_F(PasswordAutofillAgentTest, | 1501 TEST_F(PasswordAutofillAgentTest, |
1497 RememberLastNonEmptyPasswordOnSubmit_ScriptCleared) { | 1502 RememberLastNonEmptyPasswordOnSubmit_ScriptCleared) { |
1498 SimulateUsernameChangeForElement( | 1503 SimulateInputChangeForElement( |
1499 "temp", true, GetMainFrame(), username_element_, true); | 1504 "temp", true, GetMainFrame(), username_element_, true); |
1500 SimulateUsernameChangeForElement( | 1505 SimulateInputChangeForElement( |
1501 "random", true, GetMainFrame(), password_element_, true); | 1506 "random", true, GetMainFrame(), password_element_, true); |
1502 | 1507 |
1503 // Simulate that the password value was cleared by the site's JavaScript | 1508 // Simulate that the password value was cleared by the site's JavaScript |
1504 // before submit. | 1509 // before submit. |
1505 password_element_.setValue(WebString()); | 1510 password_element_.setValue(WebString()); |
1506 static_cast<content::RenderViewObserver*>(password_autofill_agent()) | 1511 static_cast<content::RenderViewObserver*>(password_autofill_agent()) |
1507 ->WillSubmitForm(GetMainFrame(), username_element_.form()); | 1512 ->WillSubmitForm(GetMainFrame(), username_element_.form()); |
1508 | 1513 |
1509 // Observe that the PasswordAutofillAgent still remembered the last non-empty | 1514 // Observe that the PasswordAutofillAgent still remembered the last non-empty |
1510 // password and sent that to the browser. | 1515 // password and sent that to the browser. |
1511 ExpectFormSubmittedWithPasswords("random", ""); | 1516 ExpectFormSubmittedWithPasswords("random", ""); |
1512 } | 1517 } |
1513 | 1518 |
1514 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time | 1519 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time |
1515 // it's the user who clears the password. This test checks that in that case, | 1520 // it's the user who clears the password. This test checks that in that case, |
1516 // the last non-empty password is not remembered. | 1521 // the last non-empty password is not remembered. |
1517 TEST_F(PasswordAutofillAgentTest, | 1522 TEST_F(PasswordAutofillAgentTest, |
1518 RememberLastNonEmptyPasswordOnSubmit_UserCleared) { | 1523 RememberLastNonEmptyPasswordOnSubmit_UserCleared) { |
1519 SimulateUsernameChangeForElement( | 1524 SimulateInputChangeForElement( |
1520 "temp", true, GetMainFrame(), username_element_, true); | 1525 "temp", true, GetMainFrame(), username_element_, true); |
1521 SimulateUsernameChangeForElement( | 1526 SimulateInputChangeForElement( |
1522 "random", true, GetMainFrame(), password_element_, true); | 1527 "random", true, GetMainFrame(), password_element_, true); |
1523 | 1528 |
1524 // Simulate that the user actually cleared the password again. | 1529 // Simulate that the user actually cleared the password again. |
1525 SimulateUsernameChangeForElement( | 1530 SimulateInputChangeForElement( |
1526 "", true, GetMainFrame(), password_element_, true); | 1531 "", true, GetMainFrame(), password_element_, true); |
1527 static_cast<content::RenderViewObserver*>(password_autofill_agent()) | 1532 static_cast<content::RenderViewObserver*>(password_autofill_agent()) |
1528 ->WillSubmitForm(GetMainFrame(), username_element_.form()); | 1533 ->WillSubmitForm(GetMainFrame(), username_element_.form()); |
1529 | 1534 |
1530 // Observe that the PasswordAutofillAgent respects the user having cleared the | 1535 // Observe that the PasswordAutofillAgent respects the user having cleared the |
1531 // password. | 1536 // password. |
1532 ExpectFormSubmittedWithPasswords("", ""); | 1537 ExpectFormSubmittedWithPasswords("", ""); |
1533 } | 1538 } |
1534 | 1539 |
1535 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the | 1540 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the |
1536 // new password instead of the current password. | 1541 // new password instead of the current password. |
1537 TEST_F(PasswordAutofillAgentTest, | 1542 TEST_F(PasswordAutofillAgentTest, |
1538 RememberLastNonEmptyPasswordOnSubmit_NewPassword) { | 1543 RememberLastNonEmptyPasswordOnSubmit_NewPassword) { |
1539 const char kNewPasswordFormHTML[] = | 1544 const char kNewPasswordFormHTML[] = |
1540 "<FORM name='LoginTestForm'>" | 1545 "<FORM name='LoginTestForm'>" |
1541 " <INPUT type='text' id='username' autocomplete='username'/>" | 1546 " <INPUT type='text' id='username' autocomplete='username'/>" |
1542 " <INPUT type='password' id='password' autocomplete='new-password'/>" | 1547 " <INPUT type='password' id='password' autocomplete='new-password'/>" |
1543 " <INPUT type='submit' value='Login'/>" | 1548 " <INPUT type='submit' value='Login'/>" |
1544 "</FORM>"; | 1549 "</FORM>"; |
1545 LoadHTML(kNewPasswordFormHTML); | 1550 LoadHTML(kNewPasswordFormHTML); |
1546 UpdateUsernameAndPasswordElements(); | 1551 UpdateUsernameAndPasswordElements(); |
1547 | 1552 |
1548 SimulateUsernameChangeForElement( | 1553 SimulateInputChangeForElement( |
1549 "temp", true, GetMainFrame(), username_element_, true); | 1554 "temp", true, GetMainFrame(), username_element_, true); |
1550 SimulateUsernameChangeForElement( | 1555 SimulateInputChangeForElement( |
1551 "random", true, GetMainFrame(), password_element_, true); | 1556 "random", true, GetMainFrame(), password_element_, true); |
1552 | 1557 |
1553 // Simulate that the password value was cleared by the site's JavaScript | 1558 // Simulate that the password value was cleared by the site's JavaScript |
1554 // before submit. | 1559 // before submit. |
1555 password_element_.setValue(WebString()); | 1560 password_element_.setValue(WebString()); |
1556 static_cast<content::RenderViewObserver*>(password_autofill_agent()) | 1561 static_cast<content::RenderViewObserver*>(password_autofill_agent()) |
1557 ->WillSubmitForm(GetMainFrame(), username_element_.form()); | 1562 ->WillSubmitForm(GetMainFrame(), username_element_.form()); |
1558 | 1563 |
1559 // Observe that the PasswordAutofillAgent still remembered the last non-empty | 1564 // Observe that the PasswordAutofillAgent still remembered the last non-empty |
1560 // password and sent that to the browser. | 1565 // password and sent that to the browser. |
1561 ExpectFormSubmittedWithPasswords("", "random"); | 1566 ExpectFormSubmittedWithPasswords("", "random"); |
1562 } | 1567 } |
1563 | 1568 |
1569 // The user first accepts a suggestion, but then overwrites the password. This | |
1570 // test checks that the overwritten password is not reverted back by the user | |
engedy
2014/08/06 10:18:17
nit: s/by/if/
vabr (Chromium)
2014/08/25 14:53:29
Done.
| |
1571 // triggering autofill through focusing (but not changing) the username again. | |
engedy
2014/08/06 10:18:17
nit: s/triggering/triggers/
vabr (Chromium)
2014/08/25 14:53:29
Done.
| |
1572 TEST_F(PasswordAutofillAgentTest, PasswordNotOverwritten) { | |
engedy
2014/08/06 10:18:17
nit: How about NoopEditingDoesNotOverwriteManually
vabr (Chromium)
2014/08/25 14:53:29
Done.
| |
1573 // Simulate having credentials which needed to wait until the user starts | |
1574 // typing the username to be filled (e.g., PSL-matched credentials). Those are | |
1575 // the ones which can be filled as a result of TextFieldDidEndEditing. | |
1576 fill_data_.wait_for_username = true; | |
1577 SimulateOnFillPasswordForm(fill_data_); | |
1578 // Simulate that the user typed her name to make the autofill work. | |
1579 SimulateInputChangeForElement(kAliceUsername, | |
1580 /*move_caret_to_end=*/true, | |
1581 GetMainFrame(), | |
1582 username_element_, | |
1583 /*is_user_input=*/true); | |
1584 SimulateDidEndEditing(GetMainFrame(), username_element_); | |
1585 const std::string old_username(username_element_.value().utf8()); | |
1586 const std::string old_password(password_element_.value().utf8()); | |
1587 const std::string new_password(old_password + "modify"); | |
1588 | |
1589 // The user changes the password. | |
1590 SimulateInputChangeForElement(new_password, | |
1591 /*move_caret_to_end=*/true, | |
1592 GetMainFrame(), | |
1593 password_element_, | |
1594 /*is_user_input=*/true); | |
1595 | |
1596 // The user switches back into the username field, but leaves that without | |
1597 // changes. | |
1598 SimulateDidEndEditing(GetMainFrame(), username_element_); | |
1599 | |
1600 // The password should have stayed as the user changed it. | |
1601 CheckTextFieldsDOMState(old_username, true, new_password, false); | |
1602 // The password should not have a suggested value. | |
1603 CheckTextFieldsState(old_username, true, std::string(), false); | |
1604 } | |
1605 | |
1606 // Tests that inline autocompletion overwrites the previous password value when | |
engedy
2014/08/06 10:18:17
nit: I would personally remove this comment, I do
vabr (Chromium)
2014/08/25 14:53:29
Done.
| |
1607 // it should. | |
1608 TEST_F(PasswordAutofillAgentTest, InlineAutocompleteOverwritesValue) { | |
engedy
2014/08/06 10:18:17
nit: How about InlineAutocompleteOverwritesManuall
vabr (Chromium)
2014/08/25 14:53:29
Done.
| |
1609 // Simulate the browser sending back the login info. | |
1610 SimulateOnFillPasswordForm(fill_data_); | |
1611 | |
1612 ClearUsernameAndPasswordFields(); | |
1613 | |
1614 // The user enters a password | |
1615 SimulateInputChangeForElement("someOtherPassword", | |
1616 /*move_caret_to_end=*/true, | |
1617 GetMainFrame(), | |
1618 password_element_, | |
1619 /*is_user_input=*/true); | |
1620 | |
1621 // Simulate the user typing a stored username. | |
1622 SimulateUsernameChange(kAliceUsername, true); | |
1623 // The autofileld password should replace the typed one. | |
1624 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | |
1625 } | |
1626 | |
1564 } // namespace autofill | 1627 } // namespace autofill |
OLD | NEW |