Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Unified Diff: chrome/renderer/autofill/password_autofill_agent_browsertest.cc

Issue 1292693004: [Password Manager] Autofill forms with field name and id attributes missing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addresses Vadym's inputs. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/autofill/password_autofill_agent_browsertest.cc
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index 01562c4c97913e6b23967874cb226a119dfc9f68..04b5bb4bc9631f41e45274bd6d55da7867f5a868 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -2085,4 +2085,169 @@ TEST_F(PasswordAutofillAgentTest,
ASSERT_FALSE(message);
}
+// Tests that credential suggestions are autofilled on a password (and change
+// password) forms having either ambiguous or empty name.
+TEST_F(PasswordAutofillAgentTest,
+ SuggestionsOnFormContainingAmbiguousOrEmptyNames) {
+ const char kEmpty[] = "";
+ const char kDummyUsernameField[] = "anonymous_username";
+ const char kDummyPasswordField[] = "anonymous_password";
+ const char kFormContainsEmptyNamesHTML[] =
+ "<FORM name='WithoutNameIdForm' action='http://www.bidule.com' >"
+ " <INPUT type='text' placeholder='username'/>"
+ " <INPUT type='password' placeholder='Password'/>"
+ " <INPUT type='submit' />"
+ "</FORM>";
+
+ const char kFormContainsAmbiguousNamesHTML[] =
+ "<FORM name='AmbiguousNameIdForm' action='http://www.bidule.com' >"
+ " <INPUT type='text' id='credentials' placeholder='username' />"
+ " <INPUT type='password' id='credentials' placeholder='Password' />"
+ " <INPUT type='submit' />"
+ "</FORM>";
+
+ const char kChangePasswordFormContainsEmptyNamesHTML[] =
+ "<FORM name='ChangePwd' action='http://www.bidule.com' >"
+ " <INPUT type='text' placeholder='username' />"
+ " <INPUT type='password' placeholder='Old Password' "
+ " autocomplete='current-password' />"
+ " <INPUT type='password' placeholder='New Password' "
+ " autocomplete='new-password' />"
+ " <INPUT type='submit' />"
+ "</FORM>";
+
+ const char kChangePasswordFormButNoUsername[] =
+ "<FORM name='ChangePwdButNoUsername' action='http://www.bidule.com' >"
+ " <INPUT type='password' placeholder='Old Password' "
+ " autocomplete='current-password' />"
+ " <INPUT type='password' placeholder='New Password' "
+ " autocomplete='new-password' />"
+ " <INPUT type='submit' />"
+ "</FORM>";
+
+ const char kChangePasswordFormButNoOldPassword[] =
+ "<FORM name='ChangePwdButNoOldPwd' action='http://www.bidule.com' >"
+ " <INPUT type='text' placeholder='username' />"
+ " <INPUT type='password' placeholder='New Password' "
+ " autocomplete='new-password' />"
+ " <INPUT type='password' placeholder='Retype Password' "
+ " autocomplete='new-password' />"
+ " <INPUT type='submit' />"
+ "</FORM>";
+
+ const char kChangePasswordFormButNoAutocompleteAttribute[] =
+ "<FORM name='ChangePwdButNoAutocomplete' action='http://www.bidule.com'>"
+ " <INPUT type='text' placeholder='username' />"
+ " <INPUT type='password' placeholder='Old Password' />"
+ " <INPUT type='password' placeholder='New Password' />"
+ " <INPUT type='submit' />"
+ "</FORM>";
+
+ const struct {
+ const char* html_form;
+ bool is_possible_change_password_form;
+ bool does_trigger_autocomplete_on_fill;
+ const char* fill_data_username_field_name;
+ const char* fill_data_password_field_name;
+ const char* expected_username_suggestions;
+ const char* expected_password_suggestions;
+ bool expected_is_username_autofillable;
+ bool expected_is_password_autofillable;
+ } test_cases[] = {
+ // Password form without name or id attributes specified for the input
+ // fields.
+ {kFormContainsEmptyNamesHTML, false, true, kDummyUsernameField,
+ kDummyPasswordField, kAliceUsername, kAlicePassword, true, true},
+
+ // Password form with ambiguous name or id attributes specified for the
+ // input fields.
+ {kFormContainsAmbiguousNamesHTML, false, true, "credentials",
+ "credentials", kAliceUsername, kAlicePassword, true, true},
+
+ // Change password form without name or id attributes specified for the
+ // input fields and |autocomplete='current-password'| attribute for old
+ // password field.
+ {kChangePasswordFormContainsEmptyNamesHTML, true, true,
+ kDummyUsernameField, kDummyPasswordField, kAliceUsername, kAlicePassword,
+ true, true},
+
+ // Change password form without username field.
+ {kChangePasswordFormButNoUsername, true, true, kEmpty,
+ kDummyPasswordField, kEmpty, kAlicePassword, false, true},
+
+ // Change password form without name or id attributes specified for the
+ // input fields and |autocomplete='new-password'| attribute for new
+ // password fields. This form *do not* trigger |OnFillPasswordForm| from
+ // browser.
+ {kChangePasswordFormButNoOldPassword, true, false, kDummyUsernameField,
+ kDummyPasswordField, kEmpty, kEmpty, false, false},
+
+ // Change password form without name or id attributes specified for the
+ // input fields but |autocomplete='current-password'| or
+ // |autocomplete='new-password'| attributes are missing for old and new
+ // password fields respectively.
+ {kChangePasswordFormButNoAutocompleteAttribute, true, true,
+ kDummyUsernameField, kDummyPasswordField, kAliceUsername, kAlicePassword,
+ true, true},
+ };
+
+ for (const auto& test_case : test_cases) {
+ SCOPED_TRACE(testing::Message() << "html_form: " << test_case.html_form
+ << ", fill_data_username_field_name: "
+ << test_case.fill_data_username_field_name
+ << ", fill_data_password_field_name: "
+ << test_case.fill_data_password_field_name);
+
+ // Load a password form.
+ LoadHTML(test_case.html_form);
+
+ // Get the username and password form input elelments.
+ blink::WebDocument document = GetMainFrame()->document();
+ blink::WebVector<blink::WebFormElement> forms;
+ document.forms(forms);
+ blink::WebFormElement form_element = forms[0];
+ std::vector<blink::WebFormControlElement> control_elements =
+ ExtractAutofillableElementsInForm(form_element);
+ bool has_fillable_username =
+ (kEmpty != test_case.fill_data_username_field_name);
+ if (has_fillable_username) {
+ username_element_ = control_elements[0].to<blink::WebInputElement>();
+ password_element_ = control_elements[1].to<blink::WebInputElement>();
+ } else {
+ password_element_ = control_elements[0].to<blink::WebInputElement>();
+ }
+
+ UpdateOriginForHTML(test_case.html_form);
+ if (test_case.does_trigger_autocomplete_on_fill) {
+ // Prepare |fill_data_| to trigger autocomplete.
+ fill_data_.is_possible_change_password_form =
+ test_case.is_possible_change_password_form;
+ fill_data_.username_field.name =
+ ASCIIToUTF16(test_case.fill_data_username_field_name);
+ fill_data_.password_field.name =
+ ASCIIToUTF16(test_case.fill_data_password_field_name);
+ fill_data_.additional_logins.clear();
+ fill_data_.other_possible_usernames.clear();
+
+ ClearUsernameAndPasswordFields();
+
+ // Simulate the browser sending back the login info, it triggers the
+ // autocomplete.
+ SimulateOnFillPasswordForm(fill_data_);
+
+ if (has_fillable_username) {
+ SimulateSuggestionChoice(username_element_);
+ } else {
+ SimulateSuggestionChoice(password_element_);
+ }
+
+ // The username and password should now have been autocompleted.
+ CheckTextFieldsDOMState(test_case.expected_username_suggestions,
+ test_case.expected_is_username_autofillable,
+ test_case.expected_password_suggestions,
+ test_case.expected_is_password_autofillable);
+ }
+ }
+}
+
} // namespace autofill

Powered by Google App Engine
This is Rietveld 408576698