Chromium Code Reviews| 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 <tuple> | 5 #include <tuple> |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/feature_list.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "chrome/renderer/autofill/password_generation_test_utils.h" | 11 #include "chrome/renderer/autofill/password_generation_test_utils.h" |
| 12 #include "chrome/test/base/chrome_render_view_test.h" | 12 #include "chrome/test/base/chrome_render_view_test.h" |
| 13 #include "components/autofill/content/common/autofill_messages.h" | 13 #include "components/autofill/content/common/autofill_messages.h" |
| 14 #include "components/autofill/content/renderer/autofill_agent.h" | 14 #include "components/autofill/content/renderer/autofill_agent.h" |
| 15 #include "components/autofill/content/renderer/form_autofill_util.h" | 15 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 16 #include "components/autofill/content/renderer/password_autofill_agent.h" | 16 #include "components/autofill/content/renderer/password_autofill_agent.h" |
| 17 #include "components/autofill/content/renderer/test_password_autofill_agent.h" | 17 #include "components/autofill/content/renderer/test_password_autofill_agent.h" |
| 18 #include "components/autofill/content/renderer/test_password_generation_agent.h" | 18 #include "components/autofill/content/renderer/test_password_generation_agent.h" |
| 19 #include "components/autofill/core/common/autofill_constants.h" | 19 #include "components/autofill/core/common/autofill_constants.h" |
| 20 #include "components/autofill/core/common/autofill_switches.h" | |
| 21 #include "components/autofill/core/common/form_data.h" | 20 #include "components/autofill/core/common/form_data.h" |
| 22 #include "components/autofill/core/common/form_field_data.h" | 21 #include "components/autofill/core/common/form_field_data.h" |
| 23 #include "components/autofill/core/common/password_form_field_prediction_map.h" | 22 #include "components/autofill/core/common/password_form_field_prediction_map.h" |
| 24 #include "content/public/renderer/render_frame.h" | 23 #include "content/public/renderer/render_frame.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 26 #include "third_party/WebKit/public/platform/WebString.h" | 25 #include "third_party/WebKit/public/platform/WebString.h" |
| 27 #include "third_party/WebKit/public/platform/WebVector.h" | 26 #include "third_party/WebKit/public/platform/WebVector.h" |
| 28 #include "third_party/WebKit/public/web/WebDocument.h" | 27 #include "third_party/WebKit/public/web/WebDocument.h" |
| 29 #include "third_party/WebKit/public/web/WebElement.h" | 28 #include "third_party/WebKit/public/web/WebElement.h" |
| 30 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 29 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
| 31 #include "third_party/WebKit/public/web/WebFormElement.h" | 30 #include "third_party/WebKit/public/web/WebFormElement.h" |
| 32 #include "third_party/WebKit/public/web/WebInputElement.h" | 31 #include "third_party/WebKit/public/web/WebInputElement.h" |
| 33 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 32 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 34 #include "third_party/WebKit/public/web/WebNode.h" | 33 #include "third_party/WebKit/public/web/WebNode.h" |
| 35 #include "third_party/WebKit/public/web/WebView.h" | 34 #include "third_party/WebKit/public/web/WebView.h" |
| 36 #include "ui/events/keycodes/keyboard_codes.h" | 35 #include "ui/events/keycodes/keyboard_codes.h" |
| 37 | 36 |
| 38 using autofill::PasswordForm; | 37 using autofill::PasswordForm; |
| 39 using base::ASCIIToUTF16; | 38 using base::ASCIIToUTF16; |
| 40 using base::UTF16ToUTF8; | 39 using base::UTF16ToUTF8; |
| 41 using blink::WebDocument; | 40 using blink::WebDocument; |
| 42 using blink::WebElement; | 41 using blink::WebElement; |
| 43 using blink::WebFrame; | 42 using blink::WebFrame; |
| 44 using blink::WebInputElement; | 43 using blink::WebInputElement; |
| 45 using blink::WebString; | 44 using blink::WebString; |
| 46 using blink::WebView; | 45 using blink::WebView; |
| 47 | 46 |
| 47 namespace password_manager { | |
|
vabr (Chromium)
2016/06/15 09:15:33
You should be able to just
#include "components/pa
jww
2016/06/15 17:17:56
components/password_manager/core/common wasn't in
vabr (Chromium)
2016/06/16 07:03:38
Acknowledged, this kind of dependency is OK.
(Also
| |
| 48 namespace features { | |
| 49 | |
| 50 extern const base::Feature kFillOnAccountSelect; | |
| 51 | |
| 52 } // namespace features | |
| 53 } // namespace password_manager | |
| 54 | |
| 48 namespace { | 55 namespace { |
| 49 | 56 |
| 50 const int kPasswordFillFormDataId = 1234; | 57 const int kPasswordFillFormDataId = 1234; |
| 51 | 58 |
| 52 // The name of the username/password element in the form. | 59 // The name of the username/password element in the form. |
| 53 const char kUsernameName[] = "username"; | 60 const char kUsernameName[] = "username"; |
| 54 const char kPasswordName[] = "password"; | 61 const char kPasswordName[] = "password"; |
| 55 const char kEmailName[] = "email"; | 62 const char kEmailName[] = "email"; |
| 56 const char kCreditCardOwnerName[] = "creditcardowner"; | 63 const char kCreditCardOwnerName[] = "creditcardowner"; |
| 57 const char kCreditCardNumberName[] = "creditcardnumber"; | 64 const char kCreditCardNumberName[] = "creditcardnumber"; |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 // Now retrieve the input elements so the test can access them. | 327 // Now retrieve the input elements so the test can access them. |
| 321 UpdateUsernameAndPasswordElements(); | 328 UpdateUsernameAndPasswordElements(); |
| 322 } | 329 } |
| 323 | 330 |
| 324 void TearDown() override { | 331 void TearDown() override { |
| 325 username_element_.reset(); | 332 username_element_.reset(); |
| 326 password_element_.reset(); | 333 password_element_.reset(); |
| 327 ChromeRenderViewTest::TearDown(); | 334 ChromeRenderViewTest::TearDown(); |
| 328 } | 335 } |
| 329 | 336 |
| 337 void SetFillOnAccountSelect() { | |
| 338 base::FeatureList::ClearInstanceForTesting(); | |
| 339 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); | |
| 340 feature_list->InitializeFromCommandLine( | |
| 341 password_manager::features::kFillOnAccountSelect.name, ""); | |
| 342 base::FeatureList::SetInstance(std::move(feature_list)); | |
| 343 } | |
| 344 | |
| 330 void UpdateOriginForHTML(const std::string& html) { | 345 void UpdateOriginForHTML(const std::string& html) { |
| 331 std::string origin = "data:text/html;charset=utf-8," + html; | 346 std::string origin = "data:text/html;charset=utf-8," + html; |
| 332 fill_data_.origin = GURL(origin); | 347 fill_data_.origin = GURL(origin); |
| 333 } | 348 } |
| 334 | 349 |
| 335 void UpdateUsernameAndPasswordElements() { | 350 void UpdateUsernameAndPasswordElements() { |
| 336 WebDocument document = GetMainFrame()->document(); | 351 WebDocument document = GetMainFrame()->document(); |
| 337 WebElement element = | 352 WebElement element = |
| 338 document.getElementById(WebString::fromUTF8(kUsernameName)); | 353 document.getElementById(WebString::fromUTF8(kUsernameName)); |
| 339 ASSERT_FALSE(element.isNull()); | 354 ASSERT_FALSE(element.isNull()); |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1283 static_cast<PageClickListener*>(autofill_agent_) | 1298 static_cast<PageClickListener*>(autofill_agent_) |
| 1284 ->FormControlElementClicked(username_element_, true); | 1299 ->FormControlElementClicked(username_element_, true); |
| 1285 CheckSuggestions("baz", true); | 1300 CheckSuggestions("baz", true); |
| 1286 ClearUsernameAndPasswordFields(); | 1301 ClearUsernameAndPasswordFields(); |
| 1287 } | 1302 } |
| 1288 | 1303 |
| 1289 // Tests that there is an autosuggestion from the password manager when the | 1304 // Tests that there is an autosuggestion from the password manager when the |
| 1290 // user clicks on the password field when FillOnAccountSelect is enabled. | 1305 // user clicks on the password field when FillOnAccountSelect is enabled. |
| 1291 TEST_F(PasswordAutofillAgentTest, | 1306 TEST_F(PasswordAutofillAgentTest, |
| 1292 FillOnAccountSelectOnlyNoCredentialsOnPasswordClick) { | 1307 FillOnAccountSelectOnlyNoCredentialsOnPasswordClick) { |
| 1293 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1308 SetFillOnAccountSelect(); |
| 1294 autofill::switches::kEnableFillOnAccountSelect); | |
| 1295 | 1309 |
| 1296 // Simulate the browser sending back the login info. | 1310 // Simulate the browser sending back the login info. |
| 1297 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); | 1311 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); |
| 1298 | 1312 |
| 1299 // Clear the text fields to start fresh. | 1313 // Clear the text fields to start fresh. |
| 1300 ClearUsernameAndPasswordFields(); | 1314 ClearUsernameAndPasswordFields(); |
| 1301 | 1315 |
| 1302 // Call SimulateElementClick() to produce a user gesture on the page so | 1316 // Call SimulateElementClick() to produce a user gesture on the page so |
| 1303 // autofill will actually fill. | 1317 // autofill will actually fill. |
| 1304 SimulateElementClick(kUsernameName); | 1318 SimulateElementClick(kUsernameName); |
| 1305 | 1319 |
| 1306 // Simulate a user clicking on the password element. This should produce no | 1320 // Simulate a user clicking on the password element. This should produce no |
| 1307 // message. | 1321 // message. |
| 1308 render_thread_->sink().ClearMessages(); | 1322 render_thread_->sink().ClearMessages(); |
| 1309 static_cast<PageClickListener*>(autofill_agent_) | 1323 static_cast<PageClickListener*>(autofill_agent_) |
| 1310 ->FormControlElementClicked(password_element_, false); | 1324 ->FormControlElementClicked(password_element_, false); |
| 1311 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( | 1325 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( |
| 1312 AutofillHostMsg_ShowPasswordSuggestions::ID)); | 1326 AutofillHostMsg_ShowPasswordSuggestions::ID)); |
| 1313 } | 1327 } |
| 1314 | 1328 |
| 1315 // Tests the autosuggestions that are given when a password element is clicked, | 1329 // Tests the autosuggestions that are given when a password element is clicked, |
| 1316 // the username element is not editable, and FillOnAccountSelect is enabled. | 1330 // the username element is not editable, and FillOnAccountSelect is enabled. |
| 1317 // Specifically, tests when the user clicks on the password element after page | 1331 // Specifically, tests when the user clicks on the password element after page |
| 1318 // load, and the corresponding username element is readonly (and thus | 1332 // load, and the corresponding username element is readonly (and thus |
| 1319 // uneditable), that the credentials for the already-filled username are | 1333 // uneditable), that the credentials for the already-filled username are |
| 1320 // suggested. | 1334 // suggested. |
| 1321 TEST_F(PasswordAutofillAgentTest, | 1335 TEST_F(PasswordAutofillAgentTest, |
| 1322 FillOnAccountSelectOnlyCredentialsOnPasswordClick) { | 1336 FillOnAccountSelectOnlyCredentialsOnPasswordClick) { |
| 1323 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1337 SetFillOnAccountSelect(); |
| 1324 autofill::switches::kEnableFillOnAccountSelect); | |
| 1325 | 1338 |
| 1326 // Simulate the browser sending back the login info. | 1339 // Simulate the browser sending back the login info. |
| 1327 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); | 1340 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); |
| 1328 | 1341 |
| 1329 // Clear the text fields to start fresh. | 1342 // Clear the text fields to start fresh. |
| 1330 ClearUsernameAndPasswordFields(); | 1343 ClearUsernameAndPasswordFields(); |
| 1331 | 1344 |
| 1332 // Simulate the page loading with a prefilled username element that is | 1345 // Simulate the page loading with a prefilled username element that is |
| 1333 // uneditable. | 1346 // uneditable. |
| 1334 username_element_.setValue("alicia"); | 1347 username_element_.setValue("alicia"); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1563 | 1576 |
| 1564 PasswordFormFillData no_username_fill_data = fill_data_; | 1577 PasswordFormFillData no_username_fill_data = fill_data_; |
| 1565 no_username_fill_data.username_field.name = base::string16(); | 1578 no_username_fill_data.username_field.name = base::string16(); |
| 1566 SimulateOnFillPasswordForm(no_username_fill_data); | 1579 SimulateOnFillPasswordForm(no_username_fill_data); |
| 1567 | 1580 |
| 1568 // The username and password should not have been autocompleted. | 1581 // The username and password should not have been autocompleted. |
| 1569 CheckTextFieldsState("", false, "", false); | 1582 CheckTextFieldsState("", false, "", false); |
| 1570 } | 1583 } |
| 1571 | 1584 |
| 1572 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnly) { | 1585 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnly) { |
| 1573 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1586 SetFillOnAccountSelect(); |
| 1574 autofill::switches::kEnableFillOnAccountSelect); | |
| 1575 | 1587 |
| 1576 ClearUsernameAndPasswordFields(); | 1588 ClearUsernameAndPasswordFields(); |
| 1577 | 1589 |
| 1578 // Simulate the browser sending back the login info for an initial page load. | 1590 // Simulate the browser sending back the login info for an initial page load. |
| 1579 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); | 1591 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); |
| 1580 | 1592 |
| 1581 CheckTextFieldsState(std::string(), false, std::string(), false); | 1593 CheckTextFieldsState(std::string(), false, std::string(), false); |
| 1582 CheckSuggestions(std::string(), true); | 1594 CheckSuggestions(std::string(), true); |
| 1583 } | 1595 } |
| 1584 | 1596 |
| 1585 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyReadonlyUsername) { | 1597 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyReadonlyUsername) { |
| 1586 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1598 SetFillOnAccountSelect(); |
| 1587 autofill::switches::kEnableFillOnAccountSelect); | |
| 1588 | 1599 |
| 1589 ClearUsernameAndPasswordFields(); | 1600 ClearUsernameAndPasswordFields(); |
| 1590 | 1601 |
| 1591 username_element_.setValue("alice"); | 1602 username_element_.setValue("alice"); |
| 1592 SetElementReadOnly(username_element_, true); | 1603 SetElementReadOnly(username_element_, true); |
| 1593 | 1604 |
| 1594 // Simulate the browser sending back the login info for an initial page load. | 1605 // Simulate the browser sending back the login info for an initial page load. |
| 1595 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); | 1606 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); |
| 1596 | 1607 |
| 1597 CheckTextFieldsState(std::string("alice"), false, std::string(), false); | 1608 CheckTextFieldsState(std::string("alice"), false, std::string(), false); |
| 1598 } | 1609 } |
| 1599 | 1610 |
| 1600 TEST_F(PasswordAutofillAgentTest, | 1611 TEST_F(PasswordAutofillAgentTest, |
| 1601 FillOnAccountSelectOnlyReadonlyNotPreferredUsername) { | 1612 FillOnAccountSelectOnlyReadonlyNotPreferredUsername) { |
| 1602 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1613 SetFillOnAccountSelect(); |
| 1603 autofill::switches::kEnableFillOnAccountSelect); | |
| 1604 | 1614 |
| 1605 ClearUsernameAndPasswordFields(); | 1615 ClearUsernameAndPasswordFields(); |
| 1606 | 1616 |
| 1607 username_element_.setValue("Carol"); | 1617 username_element_.setValue("Carol"); |
| 1608 SetElementReadOnly(username_element_, true); | 1618 SetElementReadOnly(username_element_, true); |
| 1609 | 1619 |
| 1610 // Simulate the browser sending back the login info for an initial page load. | 1620 // Simulate the browser sending back the login info for an initial page load. |
| 1611 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); | 1621 SimulateOnShowInitialPasswordAccountSuggestions(fill_data_); |
| 1612 | 1622 |
| 1613 CheckTextFieldsState(std::string("Carol"), false, std::string(), false); | 1623 CheckTextFieldsState(std::string("Carol"), false, std::string(), false); |
| 1614 } | 1624 } |
| 1615 | 1625 |
| 1616 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) { | 1626 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) { |
| 1617 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1627 SetFillOnAccountSelect(); |
| 1618 autofill::switches::kEnableFillOnAccountSelect); | |
| 1619 | 1628 |
| 1620 // Load a form with no username and update test data. | 1629 // Load a form with no username and update test data. |
| 1621 LoadHTML(kVisibleFormWithNoUsernameHTML); | 1630 LoadHTML(kVisibleFormWithNoUsernameHTML); |
| 1622 username_element_.reset(); | 1631 username_element_.reset(); |
| 1623 WebDocument document = GetMainFrame()->document(); | 1632 WebDocument document = GetMainFrame()->document(); |
| 1624 WebElement element = | 1633 WebElement element = |
| 1625 document.getElementById(WebString::fromUTF8(kPasswordName)); | 1634 document.getElementById(WebString::fromUTF8(kPasswordName)); |
| 1626 ASSERT_FALSE(element.isNull()); | 1635 ASSERT_FALSE(element.isNull()); |
| 1627 password_element_ = element.to<blink::WebInputElement>(); | 1636 password_element_ = element.to<blink::WebInputElement>(); |
| 1628 fill_data_.username_field = FormFieldData(); | 1637 fill_data_.username_field = FormFieldData(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1732 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword)); | 1741 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword)); |
| 1733 ASSERT_FALSE(render_thread_->sink().GetFirstMessageMatching( | 1742 ASSERT_FALSE(render_thread_->sink().GetFirstMessageMatching( |
| 1734 AutofillHostMsg_ShowPasswordSuggestions::ID)); | 1743 AutofillHostMsg_ShowPasswordSuggestions::ID)); |
| 1735 } | 1744 } |
| 1736 | 1745 |
| 1737 // Tests with fill-on-account-select enabled that if the username element is | 1746 // Tests with fill-on-account-select enabled that if the username element is |
| 1738 // read-only and filled with an unknown username, then the password field is not | 1747 // read-only and filled with an unknown username, then the password field is not |
| 1739 // highlighted as autofillable (regression test for https://crbug.com/442564). | 1748 // highlighted as autofillable (regression test for https://crbug.com/442564). |
| 1740 TEST_F(PasswordAutofillAgentTest, | 1749 TEST_F(PasswordAutofillAgentTest, |
| 1741 FillOnAccountSelectOnlyReadonlyUnknownUsername) { | 1750 FillOnAccountSelectOnlyReadonlyUnknownUsername) { |
| 1742 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1751 SetFillOnAccountSelect(); |
| 1743 autofill::switches::kEnableFillOnAccountSelect); | |
| 1744 | 1752 |
| 1745 ClearUsernameAndPasswordFields(); | 1753 ClearUsernameAndPasswordFields(); |
| 1746 | 1754 |
| 1747 username_element_.setValue("foobar"); | 1755 username_element_.setValue("foobar"); |
| 1748 SetElementReadOnly(username_element_, true); | 1756 SetElementReadOnly(username_element_, true); |
| 1749 | 1757 |
| 1750 CheckTextFieldsState(std::string("foobar"), false, std::string(), false); | 1758 CheckTextFieldsState(std::string("foobar"), false, std::string(), false); |
| 1751 } | 1759 } |
| 1752 | 1760 |
| 1753 // Test that the last plain text field before a password field is chosen as a | 1761 // Test that the last plain text field before a password field is chosen as a |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2373 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( | 2381 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching( |
| 2374 AutofillHostMsg_ShowPasswordSuggestions::ID)); | 2382 AutofillHostMsg_ShowPasswordSuggestions::ID)); |
| 2375 | 2383 |
| 2376 // But when the user clicks on the autofilled password field again it should | 2384 // But when the user clicks on the autofilled password field again it should |
| 2377 // still produce a suggestion dropdown. | 2385 // still produce a suggestion dropdown. |
| 2378 SimulateElementClick("password"); | 2386 SimulateElementClick("password"); |
| 2379 CheckSuggestions("", false); | 2387 CheckSuggestions("", false); |
| 2380 } | 2388 } |
| 2381 | 2389 |
| 2382 } // namespace autofill | 2390 } // namespace autofill |
| OLD | NEW |