| 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" |
| 11 #include "components/autofill/content/renderer/password_autofill_agent.h" | 11 #include "components/autofill/content/renderer/password_autofill_agent.h" |
| 12 #include "components/autofill/content/renderer/test_password_autofill_agent.h" | 12 #include "components/autofill/content/renderer/test_password_autofill_agent.h" |
| 13 #include "components/autofill/core/common/form_data.h" | 13 #include "components/autofill/core/common/form_data.h" |
| 14 #include "components/autofill/core/common/form_field_data.h" | 14 #include "components/autofill/core/common/form_field_data.h" |
| 15 #include "content/public/renderer/render_frame.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "third_party/WebKit/public/platform/WebString.h" | 17 #include "third_party/WebKit/public/platform/WebString.h" |
| 17 #include "third_party/WebKit/public/platform/WebVector.h" | 18 #include "third_party/WebKit/public/platform/WebVector.h" |
| 18 #include "third_party/WebKit/public/web/WebDocument.h" | 19 #include "third_party/WebKit/public/web/WebDocument.h" |
| 19 #include "third_party/WebKit/public/web/WebElement.h" | 20 #include "third_party/WebKit/public/web/WebElement.h" |
| 20 #include "third_party/WebKit/public/web/WebFormElement.h" | 21 #include "third_party/WebKit/public/web/WebFormElement.h" |
| 21 #include "third_party/WebKit/public/web/WebInputElement.h" | 22 #include "third_party/WebKit/public/web/WebInputElement.h" |
| 22 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 23 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 23 #include "third_party/WebKit/public/web/WebNode.h" | 24 #include "third_party/WebKit/public/web/WebNode.h" |
| 24 #include "third_party/WebKit/public/web/WebView.h" | 25 #include "third_party/WebKit/public/web/WebView.h" |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 public: | 172 public: |
| 172 PasswordAutofillAgentTest() { | 173 PasswordAutofillAgentTest() { |
| 173 } | 174 } |
| 174 | 175 |
| 175 // Simulates the fill password form message being sent to the renderer. | 176 // Simulates the fill password form message being sent to the renderer. |
| 176 // We use that so we don't have to make RenderView::OnFillPasswordForm() | 177 // We use that so we don't have to make RenderView::OnFillPasswordForm() |
| 177 // protected. | 178 // protected. |
| 178 void SimulateOnFillPasswordForm( | 179 void SimulateOnFillPasswordForm( |
| 179 const PasswordFormFillData& fill_data) { | 180 const PasswordFormFillData& fill_data) { |
| 180 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data); | 181 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data); |
| 181 static_cast<content::RenderViewObserver*>(password_autofill_agent_) | 182 static_cast<content::RenderFrameObserver*>(password_autofill_agent_) |
| 182 ->OnMessageReceived(msg); | 183 ->OnMessageReceived(msg); |
| 183 } | 184 } |
| 184 | 185 |
| 186 // As above, but fills for an iframe. |
| 187 void SimulateOnFillPasswordFormForFrame( |
| 188 WebFrame* frame, |
| 189 const PasswordFormFillData& fill_data) { |
| 190 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data); |
| 191 content::RenderFrame::FromWebFrame(frame)->OnMessageReceived(msg); |
| 192 } |
| 193 |
| 185 void SendVisiblePasswordForms() { | 194 void SendVisiblePasswordForms() { |
| 186 static_cast<content::RenderViewObserver*>(password_autofill_agent_) | 195 static_cast<content::RenderFrameObserver*>(password_autofill_agent_) |
| 187 ->DidFinishLoad(GetMainFrame()); | 196 ->DidFinishLoad(); |
| 188 } | 197 } |
| 189 | 198 |
| 190 void SetUp() override { | 199 void SetUp() override { |
| 191 ChromeRenderViewTest::SetUp(); | 200 ChromeRenderViewTest::SetUp(); |
| 192 | 201 |
| 193 // Add a preferred login and an additional login to the FillData. | 202 // Add a preferred login and an additional login to the FillData. |
| 194 username1_ = ASCIIToUTF16(kAliceUsername); | 203 username1_ = ASCIIToUTF16(kAliceUsername); |
| 195 password1_ = ASCIIToUTF16(kAlicePassword); | 204 password1_ = ASCIIToUTF16(kAlicePassword); |
| 196 username2_ = ASCIIToUTF16(kBobUsername); | 205 username2_ = ASCIIToUTF16(kBobUsername); |
| 197 password2_ = ASCIIToUTF16(kBobPassword); | 206 password2_ = ASCIIToUTF16(kBobPassword); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 WebFrame* input_frame, | 282 WebFrame* input_frame, |
| 274 WebInputElement& input, | 283 WebInputElement& input, |
| 275 bool is_user_input) { | 284 bool is_user_input) { |
| 276 input.setValue(WebString::fromUTF8(new_value), is_user_input); | 285 input.setValue(WebString::fromUTF8(new_value), is_user_input); |
| 277 // The field must have focus or AutofillAgent will think the | 286 // The field must have focus or AutofillAgent will think the |
| 278 // change should be ignored. | 287 // change should be ignored. |
| 279 while (!input.focused()) | 288 while (!input.focused()) |
| 280 input_frame->document().frame()->view()->advanceFocus(false); | 289 input_frame->document().frame()->view()->advanceFocus(false); |
| 281 if (move_caret_to_end) | 290 if (move_caret_to_end) |
| 282 input.setSelectionRange(new_value.length(), new_value.length()); | 291 input.setSelectionRange(new_value.length(), new_value.length()); |
| 283 if (is_user_input) | 292 if (is_user_input) { |
| 284 password_autofill_agent_->FirstUserGestureObserved(); | 293 AutofillMsg_FirstUserGestureObservedInTab msg(0); |
| 285 static_cast<blink::WebAutofillClient*>(autofill_agent_) | 294 content::RenderFrame::FromWebFrame(input_frame)->OnMessageReceived(msg); |
| 286 ->textFieldDidChange(input); | 295 |
| 296 // Also pass the message to the testing object. |
| 297 if (input_frame == GetMainFrame()) |
| 298 password_autofill_agent_->FirstUserGestureObserved(); |
| 299 } |
| 300 input_frame->toWebLocalFrame()->autofillClient()->textFieldDidChange(input); |
| 287 // Processing is delayed because of a Blink bug: | 301 // Processing is delayed because of a Blink bug: |
| 288 // https://bugs.webkit.org/show_bug.cgi?id=16976 | 302 // https://bugs.webkit.org/show_bug.cgi?id=16976 |
| 289 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. | 303 // See PasswordAutofillAgent::TextDidChangeInTextField() for details. |
| 290 | 304 |
| 291 // Autocomplete will trigger a style recalculation when we put up the next | 305 // Autocomplete will trigger a style recalculation when we put up the next |
| 292 // frame, but we don't want to wait that long. Instead, trigger a style | 306 // frame, but we don't want to wait that long. Instead, trigger a style |
| 293 // recalcuation manually after TextFieldDidChangeImpl runs. | 307 // recalcuation manually after TextFieldDidChangeImpl runs. |
| 294 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 308 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 295 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); | 309 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this))); |
| 296 | 310 |
| 297 base::MessageLoop::current()->RunUntilIdle(); | 311 base::MessageLoop::current()->RunUntilIdle(); |
| 298 } | 312 } |
| 299 | 313 |
| 300 void SimulateSuggestionChoice(WebInputElement& username_input) { | 314 void SimulateSuggestionChoice(WebInputElement& username_input) { |
| 301 base::string16 username(base::ASCIIToUTF16(kAliceUsername)); | 315 base::string16 username(base::ASCIIToUTF16(kAliceUsername)); |
| 302 base::string16 password(base::ASCIIToUTF16(kAlicePassword)); | 316 base::string16 password(base::ASCIIToUTF16(kAlicePassword)); |
| 303 | 317 |
| 304 // This call is necessary to setup the autofill agent appropriate for the | 318 // This call is necessary to setup the autofill agent appropriate for the |
| 305 // user selection; simulates the menu actually popping up. | 319 // user selection; simulates the menu actually popping up. |
| 306 render_thread_->sink().ClearMessages(); | 320 render_thread_->sink().ClearMessages(); |
| 307 static_cast<autofill::PageClickListener*>(autofill_agent_) | 321 static_cast<autofill::PageClickListener*>(autofill_agent_) |
| 308 ->FormControlElementClicked(username_input, false); | 322 ->FormControlElementClicked(username_input, false); |
| 309 | 323 |
| 310 AutofillMsg_FillPasswordSuggestion msg(0, username, password); | 324 AutofillMsg_FillPasswordSuggestion msg(0, username, password); |
| 311 static_cast<content::RenderViewObserver*>(autofill_agent_) | 325 static_cast<content::RenderFrameObserver*>(autofill_agent_) |
| 312 ->OnMessageReceived(msg); | 326 ->OnMessageReceived(msg); |
| 313 } | 327 } |
| 314 | 328 |
| 315 void LayoutMainFrame() { | 329 void LayoutMainFrame() { |
| 316 GetMainFrame()->view()->layout(); | 330 GetMainFrame()->view()->layout(); |
| 317 } | 331 } |
| 318 | 332 |
| 319 void SimulateUsernameChange(const std::string& username, | 333 void SimulateUsernameChange(const std::string& username, |
| 320 bool move_caret_to_end, | 334 bool move_caret_to_end, |
| 321 bool is_user_input = false) { | 335 bool is_user_input = false) { |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 std::string page_html(kWebpageWithIframeStart); | 862 std::string page_html(kWebpageWithIframeStart); |
| 849 page_html += origin; | 863 page_html += origin; |
| 850 page_html += kWebpageWithIframeEnd; | 864 page_html += kWebpageWithIframeEnd; |
| 851 | 865 |
| 852 LoadHTML(page_html.c_str()); | 866 LoadHTML(page_html.c_str()); |
| 853 | 867 |
| 854 // Set the expected form origin and action URLs. | 868 // Set the expected form origin and action URLs. |
| 855 fill_data_.origin = GURL(origin); | 869 fill_data_.origin = GURL(origin); |
| 856 fill_data_.action = GURL(origin); | 870 fill_data_.action = GURL(origin); |
| 857 | 871 |
| 858 SimulateOnFillPasswordForm(fill_data_); | |
| 859 | |
| 860 // Retrieve the input elements from the iframe since that is where we want to | 872 // Retrieve the input elements from the iframe since that is where we want to |
| 861 // test the autofill. | 873 // test the autofill. |
| 862 WebFrame* iframe = GetMainFrame()->findChildByName(kIframeName); | 874 WebFrame* iframe = GetMainFrame()->findChildByName(kIframeName); |
| 863 ASSERT_TRUE(iframe); | 875 ASSERT_TRUE(iframe); |
| 876 |
| 877 SimulateOnFillPasswordFormForFrame(iframe, fill_data_); |
| 878 |
| 864 WebDocument document = iframe->document(); | 879 WebDocument document = iframe->document(); |
| 865 | 880 |
| 866 WebElement username_element = document.getElementById(kUsernameName); | 881 WebElement username_element = document.getElementById(kUsernameName); |
| 867 WebElement password_element = document.getElementById(kPasswordName); | 882 WebElement password_element = document.getElementById(kPasswordName); |
| 868 ASSERT_FALSE(username_element.isNull()); | 883 ASSERT_FALSE(username_element.isNull()); |
| 869 ASSERT_FALSE(password_element.isNull()); | 884 ASSERT_FALSE(password_element.isNull()); |
| 870 | 885 |
| 871 WebInputElement username_input = username_element.to<WebInputElement>(); | 886 WebInputElement username_input = username_element.to<WebInputElement>(); |
| 872 WebInputElement password_input = password_element.to<WebInputElement>(); | 887 WebInputElement password_input = password_element.to<WebInputElement>(); |
| 873 ASSERT_FALSE(username_element.isNull()); | 888 ASSERT_FALSE(username_element.isNull()); |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) { | 1416 RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) { |
| 1402 SimulateInputChangeForElement( | 1417 SimulateInputChangeForElement( |
| 1403 "temp", true, GetMainFrame(), username_element_, true); | 1418 "temp", true, GetMainFrame(), username_element_, true); |
| 1404 SimulateInputChangeForElement( | 1419 SimulateInputChangeForElement( |
| 1405 "random", true, GetMainFrame(), password_element_, true); | 1420 "random", true, GetMainFrame(), password_element_, true); |
| 1406 | 1421 |
| 1407 // Simulate that the username and the password value was cleared by the | 1422 // Simulate that the username and the password value was cleared by the |
| 1408 // site's JavaScript before submit. | 1423 // site's JavaScript before submit. |
| 1409 username_element_.setValue(WebString()); | 1424 username_element_.setValue(WebString()); |
| 1410 password_element_.setValue(WebString()); | 1425 password_element_.setValue(WebString()); |
| 1411 static_cast<content::RenderViewObserver*>(password_autofill_agent_) | 1426 static_cast<content::RenderViewObserver*>(&password_autofill_agent_->legacy_) |
| 1412 ->WillSubmitForm(GetMainFrame(), username_element_.form()); | 1427 ->WillSubmitForm(GetMainFrame(), username_element_.form()); |
| 1413 | 1428 |
| 1414 // Observe that the PasswordAutofillAgent still remembered the last non-empty | 1429 // Observe that the PasswordAutofillAgent still remembered the last non-empty |
| 1415 // username and password and sent that to the browser. | 1430 // username and password and sent that to the browser. |
| 1416 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", ""); | 1431 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", ""); |
| 1417 } | 1432 } |
| 1418 | 1433 |
| 1419 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time | 1434 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time |
| 1420 // it's the user who clears the username and the password. This test checks | 1435 // it's the user who clears the username and the password. This test checks |
| 1421 // that in that case, the last non-empty username and password are not | 1436 // that in that case, the last non-empty username and password are not |
| 1422 // remembered. | 1437 // remembered. |
| 1423 TEST_F(PasswordAutofillAgentTest, | 1438 TEST_F(PasswordAutofillAgentTest, |
| 1424 RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) { | 1439 RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) { |
| 1425 SimulateInputChangeForElement( | 1440 SimulateInputChangeForElement( |
| 1426 "temp", true, GetMainFrame(), username_element_, true); | 1441 "temp", true, GetMainFrame(), username_element_, true); |
| 1427 SimulateInputChangeForElement( | 1442 SimulateInputChangeForElement( |
| 1428 "random", true, GetMainFrame(), password_element_, true); | 1443 "random", true, GetMainFrame(), password_element_, true); |
| 1429 | 1444 |
| 1430 // Simulate that the user actually cleared the username and password again. | 1445 // Simulate that the user actually cleared the username and password again. |
| 1431 SimulateInputChangeForElement("", true, GetMainFrame(), username_element_, | 1446 SimulateInputChangeForElement("", true, GetMainFrame(), username_element_, |
| 1432 true); | 1447 true); |
| 1433 SimulateInputChangeForElement( | 1448 SimulateInputChangeForElement( |
| 1434 "", true, GetMainFrame(), password_element_, true); | 1449 "", true, GetMainFrame(), password_element_, true); |
| 1435 static_cast<content::RenderViewObserver*>(password_autofill_agent_) | 1450 static_cast<content::RenderViewObserver*>(&password_autofill_agent_->legacy_) |
| 1436 ->WillSubmitForm(GetMainFrame(), username_element_.form()); | 1451 ->WillSubmitForm(GetMainFrame(), username_element_.form()); |
| 1437 | 1452 |
| 1438 // Observe that the PasswordAutofillAgent respects the user having cleared the | 1453 // Observe that the PasswordAutofillAgent respects the user having cleared the |
| 1439 // password. | 1454 // password. |
| 1440 ExpectFormSubmittedWithUsernameAndPasswords("", "", ""); | 1455 ExpectFormSubmittedWithUsernameAndPasswords("", "", ""); |
| 1441 } | 1456 } |
| 1442 | 1457 |
| 1443 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the | 1458 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the |
| 1444 // new password instead of the current password. | 1459 // new password instead of the current password. |
| 1445 TEST_F(PasswordAutofillAgentTest, | 1460 TEST_F(PasswordAutofillAgentTest, |
| 1446 RememberLastNonEmptyUsernameAndPasswordOnSubmit_New) { | 1461 RememberLastNonEmptyUsernameAndPasswordOnSubmit_New) { |
| 1447 const char kNewPasswordFormHTML[] = | 1462 const char kNewPasswordFormHTML[] = |
| 1448 "<FORM name='LoginTestForm'>" | 1463 "<FORM name='LoginTestForm'>" |
| 1449 " <INPUT type='text' id='username' autocomplete='username'/>" | 1464 " <INPUT type='text' id='username' autocomplete='username'/>" |
| 1450 " <INPUT type='password' id='password' autocomplete='new-password'/>" | 1465 " <INPUT type='password' id='password' autocomplete='new-password'/>" |
| 1451 " <INPUT type='submit' value='Login'/>" | 1466 " <INPUT type='submit' value='Login'/>" |
| 1452 "</FORM>"; | 1467 "</FORM>"; |
| 1453 LoadHTML(kNewPasswordFormHTML); | 1468 LoadHTML(kNewPasswordFormHTML); |
| 1454 UpdateUsernameAndPasswordElements(); | 1469 UpdateUsernameAndPasswordElements(); |
| 1455 | 1470 |
| 1456 SimulateInputChangeForElement( | 1471 SimulateInputChangeForElement( |
| 1457 "temp", true, GetMainFrame(), username_element_, true); | 1472 "temp", true, GetMainFrame(), username_element_, true); |
| 1458 SimulateInputChangeForElement( | 1473 SimulateInputChangeForElement( |
| 1459 "random", true, GetMainFrame(), password_element_, true); | 1474 "random", true, GetMainFrame(), password_element_, true); |
| 1460 | 1475 |
| 1461 // Simulate that the username and the password value was cleared by | 1476 // Simulate that the username and the password value was cleared by |
| 1462 // the site's JavaScript before submit. | 1477 // the site's JavaScript before submit. |
| 1463 username_element_.setValue(WebString()); | 1478 username_element_.setValue(WebString()); |
| 1464 password_element_.setValue(WebString()); | 1479 password_element_.setValue(WebString()); |
| 1465 static_cast<content::RenderViewObserver*>(password_autofill_agent_) | 1480 static_cast<content::RenderViewObserver*>(&password_autofill_agent_->legacy_) |
| 1466 ->WillSubmitForm(GetMainFrame(), username_element_.form()); | 1481 ->WillSubmitForm(GetMainFrame(), username_element_.form()); |
| 1467 | 1482 |
| 1468 // Observe that the PasswordAutofillAgent still remembered the last non-empty | 1483 // Observe that the PasswordAutofillAgent still remembered the last non-empty |
| 1469 // password and sent that to the browser. | 1484 // password and sent that to the browser. |
| 1470 ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random"); | 1485 ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random"); |
| 1471 } | 1486 } |
| 1472 | 1487 |
| 1473 // The user first accepts a suggestion, but then overwrites the password. This | 1488 // The user first accepts a suggestion, but then overwrites the password. This |
| 1474 // test checks that the overwritten password is not reverted back if the user | 1489 // test checks that the overwritten password is not reverted back if the user |
| 1475 // triggers autofill through focusing (but not changing) the username again. | 1490 // triggers autofill through focusing (but not changing) the username again. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1522 password_element_, | 1537 password_element_, |
| 1523 /*is_user_input=*/true); | 1538 /*is_user_input=*/true); |
| 1524 | 1539 |
| 1525 // Simulate the user typing a stored username. | 1540 // Simulate the user typing a stored username. |
| 1526 SimulateUsernameChange(kAliceUsername, true); | 1541 SimulateUsernameChange(kAliceUsername, true); |
| 1527 // The autofileld password should replace the typed one. | 1542 // The autofileld password should replace the typed one. |
| 1528 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 1543 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); |
| 1529 } | 1544 } |
| 1530 | 1545 |
| 1531 } // namespace autofill | 1546 } // namespace autofill |
| OLD | NEW |