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/renderer/autofill/password_generation_test_utils.h" | 7 #include "chrome/renderer/autofill/password_generation_test_utils.h" |
8 #include "chrome/test/base/chrome_render_view_test.h" | 8 #include "chrome/test/base/chrome_render_view_test.h" |
9 #include "components/autofill/content/common/autofill_messages.h" | 9 #include "components/autofill/content/common/autofill_messages.h" |
10 #include "components/autofill/content/renderer/autofill_agent.h" | 10 #include "components/autofill/content/renderer/autofill_agent.h" |
(...skipping 2067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 SimulatePasswordChange("mypassword"); | 2078 SimulatePasswordChange("mypassword"); |
2079 | 2079 |
2080 password_autofill_agent_->AJAXSucceeded(); | 2080 password_autofill_agent_->AJAXSucceeded(); |
2081 | 2081 |
2082 const IPC::Message* message = | 2082 const IPC::Message* message = |
2083 render_thread_->sink().GetFirstMessageMatching( | 2083 render_thread_->sink().GetFirstMessageMatching( |
2084 AutofillHostMsg_PasswordFormSubmitted::ID); | 2084 AutofillHostMsg_PasswordFormSubmitted::ID); |
2085 ASSERT_FALSE(message); | 2085 ASSERT_FALSE(message); |
2086 } | 2086 } |
2087 | 2087 |
| 2088 // Tests that credential suggestions are getting autofill on a password (and |
| 2089 // change password) forms having either ambiguous or empty name. |
| 2090 TEST_F(PasswordAutofillAgentTest, |
| 2091 SuggestionsOnFormContainingAmbiguousOrEmptyNames) { |
| 2092 const char kEmpty[] = ""; |
| 2093 const char kDummyUsernameField[] = "anonymous_username"; |
| 2094 const char kDummyPasswordField[] = "anonymous_password"; |
| 2095 const char kFormContainsEmptyNamesHTML[] = |
| 2096 "<FORM name='WithoutNameIdForm' action='http://www.bidule.com' >" |
| 2097 " <INPUT type='text' placeholder='username'/>" |
| 2098 " <INPUT type='password' placeholder='Password'/>" |
| 2099 " <INPUT type='submit' />" |
| 2100 "</FORM>"; |
| 2101 |
| 2102 const char kFormContainsAmbiguousNamesHTML[] = |
| 2103 "<FORM name='AmbiguousNameIdForm' action='http://www.bidule.com' >" |
| 2104 " <INPUT type='text' id='credentials' placeholder='username' />" |
| 2105 " <INPUT type='password' id='credentials' placeholder='Password' />" |
| 2106 " <INPUT type='submit' />" |
| 2107 "</FORM>"; |
| 2108 |
| 2109 const char kChangePasswordFormContainsEmptyNamesHTML[] = |
| 2110 "<FORM name='ChangePwd' action='http://www.bidule.com' >" |
| 2111 " <INPUT type='text' placeholder='username' />" |
| 2112 " <INPUT type='password' placeholder='Old Password' " |
| 2113 " autocomplete='current-password' />" |
| 2114 " <INPUT type='password' placeholder='New Password' " |
| 2115 " autocomplete='new-password' />" |
| 2116 " <INPUT type='submit' />" |
| 2117 "</FORM>"; |
| 2118 |
| 2119 const char kChangePasswordFormButNoUsername[] = |
| 2120 "<FORM name='ChangePwdButNosername' action='http://www.bidule.com' >" |
| 2121 " <INPUT type='password' placeholder='Old Password' " |
| 2122 " autocomplete='current-password' />" |
| 2123 " <INPUT type='password' placeholder='New Password' " |
| 2124 " autocomplete='new-password' />" |
| 2125 " <INPUT type='submit' />" |
| 2126 "</FORM>"; |
| 2127 |
| 2128 const char kChangePasswordFormButNoOldPassword[] = |
| 2129 "<FORM name='ChangePwdButNoOldPwd' action='http://www.bidule.com' >" |
| 2130 " <INPUT type='text' placeholder='username' />" |
| 2131 " <INPUT type='password' placeholder='New Password' " |
| 2132 " autocomplete='new-password' />" |
| 2133 " <INPUT type='password' placeholder='Retype Password' " |
| 2134 " autocomplete='new-password' />" |
| 2135 " <INPUT type='submit' />" |
| 2136 "</FORM>"; |
| 2137 |
| 2138 const char kChangePasswordFormButNoAutocompleteAttribute[] = |
| 2139 "<FORM name='ChangePwdButNoAutocomplete' action='http://www.bidule.com'>" |
| 2140 " <INPUT type='text' placeholder='username' />" |
| 2141 " <INPUT type='password' placeholder='Old Password' />" |
| 2142 " <INPUT type='password' placeholder='New Password' />" |
| 2143 " <INPUT type='submit' />" |
| 2144 "</FORM>"; |
| 2145 |
| 2146 const struct { |
| 2147 const char* html_form; |
| 2148 bool is_possible_change_password_form; |
| 2149 bool does_trigger_autocomplete_on_fill; |
| 2150 const char* fill_data_username_field_name; |
| 2151 const char* fill_data_password_field_name; |
| 2152 const char* expected_username_suggestions; |
| 2153 const char* expected_password_suggestions; |
| 2154 bool expected_is_username_autofillable; |
| 2155 bool expected_is_password_autofillable; |
| 2156 } test_cases[] = { |
| 2157 // Password form without name or id attributes specified for the input |
| 2158 // fields. |
| 2159 {kFormContainsEmptyNamesHTML, false, true, kDummyUsernameField, |
| 2160 kDummyPasswordField, kAliceUsername, kAlicePassword, true, true}, |
| 2161 |
| 2162 // Password form with ambiguous name or id attributes specified for the |
| 2163 // input fields. |
| 2164 {kFormContainsAmbiguousNamesHTML, false, true, "credentials", |
| 2165 "credentials", kAliceUsername, kAlicePassword, true, true}, |
| 2166 |
| 2167 // Change password form without name or id attributes specified for the |
| 2168 // input fields and |autocomplete='current-password'| attribute for old |
| 2169 // password field. |
| 2170 {kChangePasswordFormContainsEmptyNamesHTML, true, true, |
| 2171 kDummyUsernameField, kDummyPasswordField, kAliceUsername, kAlicePassword, |
| 2172 true, true}, |
| 2173 |
| 2174 // Change password form without optional username field. |
| 2175 {kChangePasswordFormButNoUsername, true, true, kEmpty, |
| 2176 kDummyPasswordField, kEmpty, kAlicePassword, false, true}, |
| 2177 |
| 2178 // Change password form without name or id attributes specified for the |
| 2179 // input fields and |autocomplete='new-password'| attribute for new |
| 2180 // password fields. This form do not trigger |OnFillPasswordForm| from |
| 2181 // browser. |
| 2182 {kChangePasswordFormButNoOldPassword, true, false, kDummyUsernameField, |
| 2183 kDummyPasswordField, kEmpty, kEmpty, false, false}, |
| 2184 |
| 2185 // Change password form without name or id attributes specified for the |
| 2186 // input fields but |autocomplete='current-password'| attribute is missing |
| 2187 // for old password field. This form do not trigger |OnFillPasswordForm| |
| 2188 // from browser. |
| 2189 {kChangePasswordFormButNoAutocompleteAttribute, true, false, |
| 2190 kDummyUsernameField, kDummyPasswordField, kEmpty, kEmpty, false, false}, |
| 2191 }; |
| 2192 |
| 2193 for (const auto& test_case : test_cases) { |
| 2194 SCOPED_TRACE(testing::Message() << "html_form: " << test_case.html_form |
| 2195 << ", fill_data_username_field_name: " |
| 2196 << test_case.fill_data_username_field_name |
| 2197 << ", fill_data_password_field_name: " |
| 2198 << test_case.fill_data_password_field_name); |
| 2199 |
| 2200 // Load a password form. |
| 2201 LoadHTML(test_case.html_form); |
| 2202 |
| 2203 // Get the username and password form input elelments. |
| 2204 blink::WebDocument document = GetMainFrame()->document(); |
| 2205 blink::WebVector<blink::WebFormElement> forms; |
| 2206 document.forms(forms); |
| 2207 blink::WebFormElement form_element = forms[0]; |
| 2208 std::vector<blink::WebFormControlElement> control_elements = |
| 2209 ExtractAutofillableElementsInForm(form_element); |
| 2210 bool has_fillable_username = |
| 2211 (kEmpty != test_case.fill_data_username_field_name); |
| 2212 if (has_fillable_username) { |
| 2213 username_element_ = control_elements[0].to<blink::WebInputElement>(); |
| 2214 password_element_ = control_elements[1].to<blink::WebInputElement>(); |
| 2215 } else { |
| 2216 password_element_ = control_elements[0].to<blink::WebInputElement>(); |
| 2217 } |
| 2218 |
| 2219 UpdateOriginForHTML(test_case.html_form); |
| 2220 |
| 2221 if (test_case.does_trigger_autocomplete_on_fill) { |
| 2222 // Prepare to trigger autocomplete on filling the password form. |
| 2223 fill_data_.is_possible_change_password_form = |
| 2224 test_case.is_possible_change_password_form; |
| 2225 fill_data_.username_field.name = |
| 2226 ASCIIToUTF16(test_case.fill_data_username_field_name); |
| 2227 fill_data_.password_field.name = |
| 2228 ASCIIToUTF16(test_case.fill_data_password_field_name); |
| 2229 fill_data_.additional_logins.clear(); |
| 2230 fill_data_.other_possible_usernames.clear(); |
| 2231 |
| 2232 ClearUsernameAndPasswordFields(); |
| 2233 |
| 2234 // Simulate the browser sending back the login info, it triggers the |
| 2235 // autocomplete. |
| 2236 SimulateOnFillPasswordForm(fill_data_); |
| 2237 |
| 2238 if (has_fillable_username) { |
| 2239 SimulateSuggestionChoice(username_element_); |
| 2240 } else { |
| 2241 SimulateSuggestionChoice(password_element_); |
| 2242 } |
| 2243 |
| 2244 // The username and password should now have been autocompleted. |
| 2245 CheckTextFieldsDOMState(test_case.expected_username_suggestions, |
| 2246 test_case.expected_is_username_autofillable, |
| 2247 test_case.expected_password_suggestions, |
| 2248 test_case.expected_is_password_autofillable); |
| 2249 } |
| 2250 } |
| 2251 } |
| 2252 |
2088 } // namespace autofill | 2253 } // namespace autofill |
OLD | NEW |