 Chromium Code Reviews
 Chromium Code Reviews Issue 2902113004:
  Autofill username when the user interacts with the password field.  (Closed)
    
  
    Issue 2902113004:
  Autofill username when the user interacts with the password field.  (Closed) 
  | 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 "components/autofill/content/renderer/password_autofill_agent.h" | 5 #include "components/autofill/content/renderer/password_autofill_agent.h" | 
| 6 | 6 | 
| 7 #include "base/macros.h" | 7 #include "base/macros.h" | 
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" | 
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" | 
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" | 
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 void SimulatePasswordChange(const std::string& password) { | 419 void SimulatePasswordChange(const std::string& password) { | 
| 420 SimulateUserInputChangeForElement(&password_element_, password); | 420 SimulateUserInputChangeForElement(&password_element_, password); | 
| 421 } | 421 } | 
| 422 | 422 | 
| 423 void CheckTextFieldsStateForElements(const WebInputElement& username_element, | 423 void CheckTextFieldsStateForElements(const WebInputElement& username_element, | 
| 424 const std::string& username, | 424 const std::string& username, | 
| 425 bool username_autofilled, | 425 bool username_autofilled, | 
| 426 const WebInputElement& password_element, | 426 const WebInputElement& password_element, | 
| 427 const std::string& password, | 427 const std::string& password, | 
| 428 bool password_autofilled, | 428 bool password_autofilled, | 
| 429 bool checkSuggestedValue) { | 429 bool check_suggested_username, | 
| 430 EXPECT_EQ(username, username_element.Value().Utf8()); | 430 bool check_suggested_password) { | 
| 431 EXPECT_EQ(username, check_suggested_username | |
| 432 ? username_element.SuggestedValue().Utf8() | |
| 433 : username_element.Value().Utf8()) | |
| 434 << "check_suggested_username == " << check_suggested_username; | |
| 431 EXPECT_EQ(username_autofilled, username_element.IsAutofilled()); | 435 EXPECT_EQ(username_autofilled, username_element.IsAutofilled()); | 
| 432 EXPECT_EQ(password, checkSuggestedValue | 436 | 
| 437 EXPECT_EQ(password, check_suggested_password | |
| 433 ? password_element.SuggestedValue().Utf8() | 438 ? password_element.SuggestedValue().Utf8() | 
| 434 : password_element.Value().Utf8()) | 439 : password_element.Value().Utf8()) | 
| 435 << "checkSuggestedValue == " << checkSuggestedValue; | 440 << "check_suggested_password == " << check_suggested_password; | 
| 436 EXPECT_EQ(password_autofilled, password_element.IsAutofilled()); | 441 EXPECT_EQ(password_autofilled, password_element.IsAutofilled()); | 
| 437 } | 442 } | 
| 438 | 443 | 
| 439 // Checks the DOM-accessible value of the username element and the | 444 // Checks the DOM-accessible value of the username element and the | 
| 440 // *suggested* value of the password element. | 445 // *suggested* value of the password element. | 
| 441 void CheckTextFieldsState(const std::string& username, | 446 void CheckTextFieldsState(const std::string& username, | 
| 442 bool username_autofilled, | 447 bool username_autofilled, | 
| 443 const std::string& password, | 448 const std::string& password, | 
| 444 bool password_autofilled) { | 449 bool password_autofilled) { | 
| 445 CheckTextFieldsStateForElements(username_element_, | 450 CheckTextFieldsStateForElements(username_element_, username, | 
| 446 username, | 451 username_autofilled, password_element_, | 
| 447 username_autofilled, | 452 password, password_autofilled, false, true); | 
| 
kolos1
2017/05/26 12:09:11
Could you please add description to false/true val
 
pkalinnikov
2017/05/26 16:36:52
Done.
 | |
| 448 password_element_, | |
| 449 password, | |
| 450 password_autofilled, | |
| 451 true); | |
| 452 } | 453 } | 
| 453 | 454 | 
| 454 // Checks the DOM-accessible value of the username element and the | 455 // Checks the DOM-accessible value of the username element and the | 
| 455 // DOM-accessible value of the password element. | 456 // DOM-accessible value of the password element. | 
| 456 void CheckTextFieldsDOMState(const std::string& username, | 457 void CheckTextFieldsDOMState(const std::string& username, | 
| 457 bool username_autofilled, | 458 bool username_autofilled, | 
| 458 const std::string& password, | 459 const std::string& password, | 
| 459 bool password_autofilled) { | 460 bool password_autofilled) { | 
| 460 CheckTextFieldsStateForElements(username_element_, | 461 CheckTextFieldsStateForElements( | 
| 461 username, | 462 username_element_, username, username_autofilled, password_element_, | 
| 462 username_autofilled, | 463 password, password_autofilled, false, false); | 
| 463 password_element_, | 464 } | 
| 464 password, | 465 | 
| 465 password_autofilled, | 466 // Checks the suggested values of the |username| and |password| elements. | 
| 466 false); | 467 void CheckTextFieldsSuggestedState(const std::string& username, | 
| 468 bool username_autofilled, | |
| 469 const std::string& password, | |
| 470 bool password_autofilled) { | |
| 471 CheckTextFieldsStateForElements(username_element_, username, | |
| 472 username_autofilled, password_element_, | |
| 473 password, password_autofilled, true, true); | |
| 474 } | |
| 475 | |
| 476 void ResetFieldState(WebInputElement* element, | |
| 477 const std::string& value = std::string(), | |
| 478 bool is_autofilled = false) { | |
| 479 element->SetValue(WebString::FromUTF8(value)); | |
| 480 element->SetSuggestedValue(WebString()); | |
| 481 element->SetAutofilled(is_autofilled); | |
| 482 element->SetSelectionRange(value.size(), value.size()); | |
| 467 } | 483 } | 
| 468 | 484 | 
| 469 void CheckUsernameSelection(int start, int end) { | 485 void CheckUsernameSelection(int start, int end) { | 
| 470 EXPECT_EQ(start, username_element_.SelectionStart()); | 486 EXPECT_EQ(start, username_element_.SelectionStart()); | 
| 471 EXPECT_EQ(end, username_element_.SelectionEnd()); | 487 EXPECT_EQ(end, username_element_.SelectionEnd()); | 
| 472 } | 488 } | 
| 473 | 489 | 
| 474 // Checks the message sent to PasswordAutofillManager to build the suggestion | 490 // Checks the message sent to PasswordAutofillManager to build the suggestion | 
| 475 // list. |username| is the expected username field value, and |show_all| is | 491 // list. |username| is the expected username field value, and |show_all| is | 
| 476 // the expected flag for the PasswordAutofillManager, whether to show all | 492 // the expected flag for the PasswordAutofillManager, whether to show all | 
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1121 CheckIfEventsAreCalled(event_checkers, true); | 1137 CheckIfEventsAreCalled(event_checkers, true); | 
| 1122 } | 1138 } | 
| 1123 | 1139 | 
| 1124 // Tests that |FillSuggestion| properly fills the username and password. | 1140 // Tests that |FillSuggestion| properly fills the username and password. | 
| 1125 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { | 1141 TEST_F(PasswordAutofillAgentTest, FillSuggestion) { | 
| 1126 // Simulate the browser sending the login info, but set |wait_for_username| | 1142 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 1127 // to prevent the form from being immediately filled. | 1143 // to prevent the form from being immediately filled. | 
| 1128 fill_data_.wait_for_username = true; | 1144 fill_data_.wait_for_username = true; | 
| 1129 SimulateOnFillPasswordForm(fill_data_); | 1145 SimulateOnFillPasswordForm(fill_data_); | 
| 1130 | 1146 | 
| 1131 // Neither field should have been autocompleted. | 1147 for (const auto& element : {username_element_, password_element_}) { | 
| 1132 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 1148 // Neither field should be autocompleted. | 
| 1149 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | |
| 1133 | 1150 | 
| 1134 // If the password field is not autocompletable, it should not be affected. | 1151 // If the password field is not autocompletable, it should not be affected. | 
| 1135 SetElementReadOnly(password_element_, true); | 1152 SetElementReadOnly(password_element_, true); | 
| 1136 EXPECT_FALSE(password_autofill_agent_->FillSuggestion( | 1153 EXPECT_FALSE(password_autofill_agent_->FillSuggestion( | 
| 1137 username_element_, ASCIIToUTF16(kAliceUsername), | 1154 element, ASCIIToUTF16(kAliceUsername), ASCIIToUTF16(kAlicePassword))); | 
| 1138 ASCIIToUTF16(kAlicePassword))); | 1155 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 
| 1139 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 1156 SetElementReadOnly(password_element_, false); | 
| 1140 SetElementReadOnly(password_element_, false); | |
| 1141 | 1157 | 
| 1142 // After filling with the suggestion, both fields should be autocompleted. | 1158 // After filling with the suggestion, both fields should be autocompleted. | 
| 1143 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 1159 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 
| 1144 username_element_, ASCIIToUTF16(kAliceUsername), | 1160 element, ASCIIToUTF16(kAliceUsername), ASCIIToUTF16(kAlicePassword))); | 
| 1145 ASCIIToUTF16(kAlicePassword))); | 1161 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 
| 1146 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 1162 int username_length = strlen(kAliceUsername); | 
| 1147 int username_length = strlen(kAliceUsername); | 1163 CheckUsernameSelection(username_length, username_length); | 
| 1148 CheckUsernameSelection(username_length, username_length); | |
| 1149 | 1164 | 
| 1150 // Try Filling with a suggestion with password different from the one that was | 1165 // Try Filling with a suggestion with password different from the one that | 
| 1151 // initially sent to the renderer. | 1166 // was initially sent to the renderer. | 
| 1152 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 1167 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 
| 1153 username_element_, ASCIIToUTF16(kBobUsername), | 1168 element, ASCIIToUTF16(kBobUsername), ASCIIToUTF16(kCarolPassword))); | 
| 1154 ASCIIToUTF16(kCarolPassword))); | 1169 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true); | 
| 1155 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true); | 1170 username_length = strlen(kBobUsername); | 
| 1156 username_length = strlen(kBobUsername); | 1171 CheckUsernameSelection(username_length, username_length); | 
| 1157 CheckUsernameSelection(username_length, username_length); | 1172 | 
| 1173 ClearUsernameAndPasswordFields(); | |
| 1174 } | |
| 1158 } | 1175 } | 
| 1159 | 1176 | 
| 1160 // Tests that |FillSuggestion| properly fills the password if username is | 1177 // Tests that |FillSuggestion| doesn't change non-empty non-autofilled username | 
| 1161 // read-only. | 1178 // when interacting with the password field. | 
| 1179 TEST_F(PasswordAutofillAgentTest, | |
| 1180 FillSuggestionFromPasswordFieldWithUsernameManuallyFilled) { | |
| 1181 username_element_.SetValue(WebString::FromUTF8("user1")); | |
| 1182 | |
| 1183 // Simulate the browser sending the login info, but set |wait_for_username| to | |
| 1184 // prevent the form from being immediately filled. | |
| 1185 fill_data_.wait_for_username = true; | |
| 1186 SimulateOnFillPasswordForm(fill_data_); | |
| 1187 // Neither field should have been autocompleted. | |
| 1188 CheckTextFieldsDOMState("user1", false, std::string(), false); | |
| 1189 | |
| 1190 // Only password field should be autocompleted. | |
| 1191 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | |
| 1192 password_element_, ASCIIToUTF16(kAliceUsername), | |
| 1193 ASCIIToUTF16(kAlicePassword))); | |
| 1194 CheckTextFieldsDOMState("user1", false, kAlicePassword, true); | |
| 1195 | |
| 1196 // Try Filling with a different password. Only password should be changed. | |
| 1197 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | |
| 1198 password_element_, ASCIIToUTF16(kBobUsername), | |
| 1199 ASCIIToUTF16(kCarolPassword))); | |
| 1200 CheckTextFieldsDOMState("user1", false, kCarolPassword, true); | |
| 1201 } | |
| 1202 | |
| 1203 // Tests that |FillSuggestion| properly fills the password if the username field | |
| 1204 // is read-only. | |
| 1162 TEST_F(PasswordAutofillAgentTest, FillSuggestionIfUsernameReadOnly) { | 1205 TEST_F(PasswordAutofillAgentTest, FillSuggestionIfUsernameReadOnly) { | 
| 1163 // Simulate the browser sending the login info. | 1206 // Simulate the browser sending the login info. | 
| 1164 SetElementReadOnly(username_element_, true); | 1207 SetElementReadOnly(username_element_, true); | 
| 1165 SimulateOnFillPasswordForm(fill_data_); | 1208 SimulateOnFillPasswordForm(fill_data_); | 
| 1166 | 1209 | 
| 1167 // Neither field should have been autocompleted. | 1210 for (const auto& element : {username_element_, password_element_}) { | 
| 
kolos1
2017/05/26 12:09:10
Could we change |element| to sth more descriptive?
 
pkalinnikov
2017/05/26 16:36:52
selected_element? Done.
 
kolos1
2017/05/29 09:17:11
ah, sure.
 | |
| 1168 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 1211 // Neither field should be autocompleted. | 
| 1212 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | |
| 1169 | 1213 | 
| 1170 // Username field is not autocompletable, it should not be affected. | 1214 // Username field is not autocompletable, it should not be affected. | 
| 1171 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 1215 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 
| 1172 password_element_, ASCIIToUTF16(kAliceUsername), | 1216 element, ASCIIToUTF16(kAliceUsername), ASCIIToUTF16(kAlicePassword))); | 
| 1173 ASCIIToUTF16(kAlicePassword))); | 1217 CheckTextFieldsDOMState(std::string(), false, kAlicePassword, true); | 
| 1174 CheckTextFieldsDOMState(std::string(), false, kAlicePassword, true); | |
| 1175 | 1218 | 
| 1176 // Try Filling with a suggestion with password different from the one that was | 1219 // Try Filling with a suggestion with password different from the one that | 
| 1177 // initially sent to the renderer. | 1220 // was initially sent to the renderer. | 
| 1178 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 1221 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 
| 1179 password_element_, ASCIIToUTF16(kBobUsername), | 1222 element, ASCIIToUTF16(kBobUsername), ASCIIToUTF16(kCarolPassword))); | 
| 1180 ASCIIToUTF16(kCarolPassword))); | 1223 CheckTextFieldsDOMState(std::string(), false, kCarolPassword, true); | 
| 1181 CheckTextFieldsDOMState(std::string(), false, kCarolPassword, true); | 1224 | 
| 1225 ClearUsernameAndPasswordFields(); | |
| 
kolos1
2017/05/26 12:09:10
Shall we also call PasswordAutofillAgent::ClearPre
 
pkalinnikov
2017/05/26 16:36:52
ClearPreview is private. We could invoke DidClearA
 
kolos1
2017/05/29 09:17:11
Looks good. Thx.
 | |
| 1226 } | |
| 1182 } | 1227 } | 
| 1183 | 1228 | 
| 1184 // Tests that |PreviewSuggestion| properly previews the username and password. | 1229 // Tests that |PreviewSuggestion| properly previews the username and password. | 
| 1185 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) { | 1230 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) { | 
| 1186 // Simulate the browser sending the login info, but set |wait_for_username| | 1231 // Simulate the browser sending the login info, but set |wait_for_username| to | 
| 1187 // to prevent the form from being immediately filled. | 1232 // prevent the form from being immediately filled. | 
| 1188 fill_data_.wait_for_username = true; | 1233 fill_data_.wait_for_username = true; | 
| 1189 SimulateOnFillPasswordForm(fill_data_); | 1234 SimulateOnFillPasswordForm(fill_data_); | 
| 1190 | 1235 | 
| 1236 for (const auto& element : {username_element_, password_element_}) { | |
| 1237 // Neither field should be autocompleted. | |
| 1238 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | |
| 1239 | |
| 1240 // If the password field is not autocompletable, it should not be affected. | |
| 1241 SetElementReadOnly(password_element_, true); | |
| 1242 EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion( | |
| 1243 element, kAliceUsername, kAlicePassword)); | |
| 1244 CheckTextFieldsSuggestedState(std::string(), false, std::string(), false); | |
| 1245 SetElementReadOnly(password_element_, false); | |
| 1246 | |
| 1247 // After selecting the suggestion, both fields should be previewed with | |
| 1248 // suggested values. | |
| 1249 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | |
| 1250 element, kAliceUsername, kAlicePassword)); | |
| 1251 CheckTextFieldsSuggestedState(kAliceUsername, true, kAlicePassword, true); | |
| 1252 int username_length = strlen(kAliceUsername); | |
| 1253 CheckUsernameSelection(0, username_length); | |
| 1254 | |
| 1255 // Try previewing with a password different from the one that was initially | |
| 1256 // sent to the renderer. | |
| 
kolos1
2017/05/26 12:09:10
No sure I am understand what we test here. Please
 
pkalinnikov
2017/05/26 16:36:52
This comment was added when this test was introduc
 
kolos1
2017/05/29 09:17:11
Yes, let's keep as it is.
I believe it came from
 | |
| 1257 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | |
| 1258 element, kBobUsername, kCarolPassword)); | |
| 1259 CheckTextFieldsSuggestedState(kBobUsername, true, kCarolPassword, true); | |
| 1260 username_length = strlen(kBobUsername); | |
| 1261 CheckUsernameSelection(0, username_length); | |
| 1262 | |
| 1263 ClearUsernameAndPasswordFields(); | |
| 1264 } | |
| 1265 } | |
| 1266 | |
| 1267 // Tests that |PreviewSuggestion| doesn't change non-empty non-autofilled | |
| 1268 // username when previewing autofills on interacting with the password field. | |
| 1269 TEST_F(PasswordAutofillAgentTest, | |
| 1270 PreviewSuggestionFromPasswordFieldWithUsernameManuallyFilled) { | |
| 1271 username_element_.SetValue(WebString::FromUTF8("user1")); | |
| 1272 | |
| 1273 // Simulate the browser sending the login info, but set |wait_for_username| to | |
| 1274 // prevent the form from being immediately filled. | |
| 1275 fill_data_.wait_for_username = true; | |
| 1276 SimulateOnFillPasswordForm(fill_data_); | |
| 1191 // Neither field should have been autocompleted. | 1277 // Neither field should have been autocompleted. | 
| 1192 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 1278 CheckTextFieldsDOMState("user1", false, std::string(), false); | 
| 1193 | 1279 | 
| 1194 // If the password field is not autocompletable, it should not be affected. | 1280 // Only password field should be autocompleted. | 
| 1195 SetElementReadOnly(password_element_, true); | 1281 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1196 EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion( | 1282 password_element_, kAliceUsername, kAlicePassword)); | 
| 1197 username_element_, kAliceUsername, kAlicePassword)); | 1283 CheckTextFieldsSuggestedState(std::string(), false, kAlicePassword, true); | 
| 1198 EXPECT_EQ(std::string(), username_element_.SuggestedValue().Utf8()); | 1284 CheckTextFieldsDOMState("user1", false, std::string(), true); | 
| 1199 EXPECT_FALSE(username_element_.IsAutofilled()); | |
| 1200 EXPECT_EQ(std::string(), password_element_.SuggestedValue().Utf8()); | |
| 1201 EXPECT_FALSE(password_element_.IsAutofilled()); | |
| 1202 SetElementReadOnly(password_element_, false); | |
| 1203 | 1285 | 
| 1204 // After selecting the suggestion, both fields should be previewed | 1286 // Try previewing with a different password. Only password should be changed. | 
| 1205 // with suggested values. | |
| 1206 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1287 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1207 username_element_, kAliceUsername, kAlicePassword)); | 1288 password_element_, kBobUsername, kCarolPassword)); | 
| 1208 EXPECT_EQ(kAliceUsername, username_element_.SuggestedValue().Utf8()); | 1289 CheckTextFieldsSuggestedState(std::string(), false, kCarolPassword, true); | 
| 1209 EXPECT_TRUE(username_element_.IsAutofilled()); | 1290 CheckTextFieldsDOMState("user1", false, std::string(), true); | 
| 1210 EXPECT_EQ(kAlicePassword, password_element_.SuggestedValue().Utf8()); | |
| 1211 EXPECT_TRUE(password_element_.IsAutofilled()); | |
| 1212 int username_length = strlen(kAliceUsername); | |
| 1213 CheckUsernameSelection(0, username_length); | |
| 1214 | |
| 1215 // Try previewing with a password different from the one that was initially | |
| 1216 // sent to the renderer. | |
| 1217 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | |
| 1218 username_element_, kBobUsername, kCarolPassword)); | |
| 1219 EXPECT_EQ(kBobUsername, username_element_.SuggestedValue().Utf8()); | |
| 1220 EXPECT_TRUE(username_element_.IsAutofilled()); | |
| 1221 EXPECT_EQ(kCarolPassword, password_element_.SuggestedValue().Utf8()); | |
| 1222 EXPECT_TRUE(password_element_.IsAutofilled()); | |
| 1223 username_length = strlen(kBobUsername); | |
| 1224 CheckUsernameSelection(0, username_length); | |
| 1225 } | 1291 } | 
| 1226 | 1292 | 
| 1227 // Tests that |PreviewSuggestion| properly previews the password if username is | 1293 // Tests that |PreviewSuggestion| properly previews the password if username is | 
| 1228 // read-only. | 1294 // read-only. | 
| 1229 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionIfUsernameReadOnly) { | 1295 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionIfUsernameReadOnly) { | 
| 1230 // Simulate the browser sending the login info. | 1296 // Simulate the browser sending the login info. | 
| 1231 SetElementReadOnly(username_element_, true); | 1297 SetElementReadOnly(username_element_, true); | 
| 1232 SimulateOnFillPasswordForm(fill_data_); | 1298 SimulateOnFillPasswordForm(fill_data_); | 
| 1233 | 1299 | 
| 1234 // Neither field should have been autocompleted. | 1300 for (const auto& element : {username_element_, password_element_}) { | 
| 1235 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 1301 // Neither field should be autocompleted. | 
| 1302 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | |
| 1236 | 1303 | 
| 1237 // Username field is not autocompletable, it should not be affected. | 1304 // Username field is not autocompletable, it should not be affected. | 
| 1238 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1305 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1239 password_element_, kAliceUsername, kAlicePassword)); | 1306 element, kAliceUsername, kAlicePassword)); | 
| 1240 EXPECT_EQ(std::string(), username_element_.SuggestedValue().Utf8()); | 1307 // Password field must be autofilled. | 
| 1241 EXPECT_FALSE(username_element_.IsAutofilled()); | 1308 CheckTextFieldsSuggestedState(std::string(), false, kAlicePassword, true); | 
| 1242 | 1309 | 
| 1243 // Password field must be autofilled. | 1310 // Try previewing with a password different from the one that was initially | 
| 1244 EXPECT_EQ(kAlicePassword, password_element_.SuggestedValue().Utf8()); | 1311 // sent to the renderer. | 
| 1245 EXPECT_TRUE(password_element_.IsAutofilled()); | 1312 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1313 element, kBobUsername, kCarolPassword)); | |
| 1314 CheckTextFieldsSuggestedState(std::string(), false, kCarolPassword, true); | |
| 1246 | 1315 | 
| 1247 // Try previewing with a password different from the one that was initially | 1316 ClearUsernameAndPasswordFields(); | 
| 1248 // sent to the renderer. | 1317 } | 
| 1249 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | |
| 1250 password_element_, kBobUsername, kCarolPassword)); | |
| 1251 EXPECT_EQ(std::string(), username_element_.SuggestedValue().Utf8()); | |
| 1252 EXPECT_FALSE(username_element_.IsAutofilled()); | |
| 1253 EXPECT_EQ(kCarolPassword, password_element_.SuggestedValue().Utf8()); | |
| 1254 EXPECT_TRUE(password_element_.IsAutofilled()); | |
| 1255 } | 1318 } | 
| 1256 | 1319 | 
| 1257 // Tests that |PreviewSuggestion| properly sets the username selection range. | 1320 // Tests that |PreviewSuggestion| properly sets the username selection range. | 
| 1258 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) { | 1321 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) { | 
| 1259 username_element_.SetValue(WebString::FromUTF8("ali")); | |
| 1260 username_element_.SetSelectionRange(3, 3); | |
| 1261 username_element_.SetAutofilled(true); | |
| 1262 | |
| 1263 CheckTextFieldsDOMState("ali", true, std::string(), false); | |
| 1264 | |
| 1265 // Simulate the browser sending the login info, but set |wait_for_username| | 1322 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 1266 // to prevent the form from being immediately filled. | 1323 // to prevent the form from being immediately filled. | 
| 1267 fill_data_.wait_for_username = true; | 1324 fill_data_.wait_for_username = true; | 
| 1268 SimulateOnFillPasswordForm(fill_data_); | 1325 SimulateOnFillPasswordForm(fill_data_); | 
| 1269 | 1326 | 
| 1270 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1327 for (const auto& element : {username_element_, password_element_}) { | 
| 1271 username_element_, kAliceUsername, kAlicePassword)); | 1328 ResetFieldState(&username_element_, "ali", true); | 
| 1272 EXPECT_EQ(kAliceUsername, username_element_.SuggestedValue().Utf8()); | 1329 ResetFieldState(&password_element_); | 
| 1273 EXPECT_TRUE(username_element_.IsAutofilled()); | 1330 | 
| 1274 EXPECT_EQ(kAlicePassword, password_element_.SuggestedValue().Utf8()); | 1331 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1275 EXPECT_TRUE(password_element_.IsAutofilled()); | 1332 element, kAliceUsername, kAlicePassword)); | 
| 1276 int username_length = strlen(kAliceUsername); | 1333 CheckTextFieldsSuggestedState(kAliceUsername, true, kAlicePassword, true); | 
| 1277 CheckUsernameSelection(3, username_length); | 1334 int username_length = strlen(kAliceUsername); | 
| 1335 CheckUsernameSelection(3, username_length); | |
| 1336 } | |
| 1278 } | 1337 } | 
| 1279 | 1338 | 
| 1280 // Tests that |ClearPreview| properly clears previewed username and password | 1339 // Tests that |ClearPreview| properly clears previewed username and password | 
| 1281 // with password being previously autofilled. | 1340 // with password being previously autofilled. | 
| 1282 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) { | 1341 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) { | 
| 1283 password_element_.SetValue(WebString::FromUTF8("sec")); | 1342 ResetFieldState(&password_element_, "sec", true); | 
| 1284 password_element_.SetAutofilled(true); | |
| 1285 | 1343 | 
| 1286 // Simulate the browser sending the login info, but set |wait_for_username| | 1344 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 1287 // to prevent the form from being immediately filled. | 1345 // to prevent the form from being immediately filled. | 
| 1288 fill_data_.wait_for_username = true; | 1346 fill_data_.wait_for_username = true; | 
| 1289 SimulateOnFillPasswordForm(fill_data_); | 1347 SimulateOnFillPasswordForm(fill_data_); | 
| 1290 | 1348 | 
| 1291 CheckTextFieldsDOMState(std::string(), false, "sec", true); | 1349 CheckTextFieldsDOMState(std::string(), false, "sec", true); | 
| 1292 | 1350 | 
| 1293 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1351 for (const auto& element : {username_element_, password_element_}) { | 
| 1294 username_element_, kAliceUsername, kAlicePassword)); | 1352 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1353 element, kAliceUsername, kAlicePassword)); | |
| 1354 EXPECT_TRUE(password_autofill_agent_->DidClearAutofillSelection(element)); | |
| 1295 | 1355 | 
| 1296 EXPECT_TRUE( | 1356 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 
| 1297 password_autofill_agent_->DidClearAutofillSelection(username_element_)); | 1357 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | 
| 1298 | 1358 CheckTextFieldsDOMState(std::string(), false, "sec", true); | 
| 1299 EXPECT_TRUE(username_element_.Value().IsEmpty()); | 1359 CheckUsernameSelection(0, 0); | 
| 1300 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 1360 } | 
| 1301 EXPECT_FALSE(username_element_.IsAutofilled()); | |
| 1302 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.Value().Utf16()); | |
| 1303 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | |
| 1304 EXPECT_TRUE(password_element_.IsAutofilled()); | |
| 1305 CheckUsernameSelection(0, 0); | |
| 1306 } | 1361 } | 
| 1307 | 1362 | 
| 1308 // Tests that |ClearPreview| properly clears previewed username and password | 1363 // Tests that |ClearPreview| properly clears previewed username and password | 
| 1309 // with username being previously autofilled. | 1364 // with username being previously autofilled. | 
| 1310 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) { | 1365 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) { | 
| 1311 username_element_.SetValue(WebString::FromUTF8("ali")); | 1366 ResetFieldState(&username_element_, "ali", true); | 
| 1312 username_element_.SetSelectionRange(3, 3); | 1367 username_element_.SetSelectionRange(3, 3); | 
| 1313 username_element_.SetAutofilled(true); | |
| 1314 | 1368 | 
| 1315 // Simulate the browser sending the login info, but set |wait_for_username| | 1369 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 1316 // to prevent the form from being immediately filled. | 1370 // to prevent the form from being immediately filled. | 
| 1317 fill_data_.wait_for_username = true; | 1371 fill_data_.wait_for_username = true; | 
| 1318 SimulateOnFillPasswordForm(fill_data_); | 1372 SimulateOnFillPasswordForm(fill_data_); | 
| 1319 | 1373 | 
| 1320 CheckTextFieldsDOMState("ali", true, std::string(), false); | 1374 CheckTextFieldsDOMState("ali", true, std::string(), false); | 
| 1321 | 1375 | 
| 1322 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1376 for (const auto& element : {username_element_, password_element_}) { | 
| 1323 username_element_, kAliceUsername, kAlicePassword)); | 1377 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1378 element, kAliceUsername, kAlicePassword)); | |
| 1379 EXPECT_TRUE(password_autofill_agent_->DidClearAutofillSelection(element)); | |
| 1324 | 1380 | 
| 1325 EXPECT_TRUE( | 1381 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 
| 1326 password_autofill_agent_->DidClearAutofillSelection(username_element_)); | 1382 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | 
| 1327 | 1383 CheckTextFieldsDOMState("ali", true, std::string(), false); | 
| 1328 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.Value().Utf16()); | 1384 CheckUsernameSelection(3, 3); | 
| 1329 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 1385 } | 
| 1330 EXPECT_TRUE(username_element_.IsAutofilled()); | |
| 1331 EXPECT_TRUE(password_element_.Value().IsEmpty()); | |
| 1332 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | |
| 1333 EXPECT_FALSE(password_element_.IsAutofilled()); | |
| 1334 CheckUsernameSelection(3, 3); | |
| 1335 } | 1386 } | 
| 1336 | 1387 | 
| 1337 // Tests that |ClearPreview| properly clears previewed username and password | 1388 // Tests that |ClearPreview| properly clears previewed username and password | 
| 1338 // with username and password being previously autofilled. | 1389 // with username and password being previously autofilled. | 
| 1339 TEST_F(PasswordAutofillAgentTest, | 1390 TEST_F(PasswordAutofillAgentTest, | 
| 1340 ClearPreviewWithAutofilledUsernameAndPassword) { | 1391 ClearPreviewWithAutofilledUsernameAndPassword) { | 
| 1341 username_element_.SetValue(WebString::FromUTF8("ali")); | 1392 ResetFieldState(&username_element_, "ali", true); | 
| 1342 username_element_.SetSelectionRange(3, 3); | 1393 ResetFieldState(&password_element_, "sec", true); | 
| 1343 username_element_.SetAutofilled(true); | |
| 1344 password_element_.SetValue(WebString::FromUTF8("sec")); | |
| 1345 password_element_.SetAutofilled(true); | |
| 1346 | 1394 | 
| 1347 // Simulate the browser sending the login info, but set |wait_for_username| | 1395 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 1348 // to prevent the form from being immediately filled. | 1396 // to prevent the form from being immediately filled. | 
| 1349 fill_data_.wait_for_username = true; | 1397 fill_data_.wait_for_username = true; | 
| 1350 SimulateOnFillPasswordForm(fill_data_); | 1398 SimulateOnFillPasswordForm(fill_data_); | 
| 1351 | 1399 | 
| 1352 CheckTextFieldsDOMState("ali", true, "sec", true); | 1400 CheckTextFieldsDOMState("ali", true, "sec", true); | 
| 1353 | 1401 | 
| 1354 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1402 for (const auto& element : {username_element_, password_element_}) { | 
| 1355 username_element_, kAliceUsername, kAlicePassword)); | 1403 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1404 element, kAliceUsername, kAlicePassword)); | |
| 1405 EXPECT_TRUE(password_autofill_agent_->DidClearAutofillSelection(element)); | |
| 1356 | 1406 | 
| 1357 EXPECT_TRUE( | 1407 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 
| 1358 password_autofill_agent_->DidClearAutofillSelection(username_element_)); | 1408 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | 
| 1359 | 1409 CheckTextFieldsDOMState("ali", true, "sec", true); | 
| 1360 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.Value().Utf16()); | 1410 CheckUsernameSelection(3, 3); | 
| 1361 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 1411 } | 
| 1362 EXPECT_TRUE(username_element_.IsAutofilled()); | |
| 1363 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.Value().Utf16()); | |
| 1364 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | |
| 1365 EXPECT_TRUE(password_element_.IsAutofilled()); | |
| 1366 CheckUsernameSelection(3, 3); | |
| 1367 } | 1412 } | 
| 1368 | 1413 | 
| 1369 // Tests that |ClearPreview| properly clears previewed username and password | 1414 // Tests that |ClearPreview| properly clears previewed username and password | 
| 1370 // with neither username nor password being previously autofilled. | 1415 // with neither username nor password being previously autofilled. | 
| 1371 TEST_F(PasswordAutofillAgentTest, | 1416 TEST_F(PasswordAutofillAgentTest, | 
| 1372 ClearPreviewWithNotAutofilledUsernameAndPassword) { | 1417 ClearPreviewWithNotAutofilledUsernameAndPassword) { | 
| 1373 // Simulate the browser sending the login info, but set |wait_for_username| | 1418 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 1374 // to prevent the form from being immediately filled. | 1419 // to prevent the form from being immediately filled. | 
| 1375 fill_data_.wait_for_username = true; | 1420 fill_data_.wait_for_username = true; | 
| 1376 SimulateOnFillPasswordForm(fill_data_); | 1421 SimulateOnFillPasswordForm(fill_data_); | 
| 1377 | 1422 | 
| 1378 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 1423 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 
| 1379 | 1424 | 
| 1380 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 1425 for (const auto& element : {username_element_, password_element_}) { | 
| 1381 username_element_, kAliceUsername, kAlicePassword)); | 1426 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion( | 
| 1427 element, kAliceUsername, kAlicePassword)); | |
| 1428 EXPECT_TRUE(password_autofill_agent_->DidClearAutofillSelection(element)); | |
| 1382 | 1429 | 
| 1383 EXPECT_TRUE( | 1430 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 
| 1384 password_autofill_agent_->DidClearAutofillSelection(username_element_)); | 1431 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | 
| 1385 | 1432 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 
| 1386 EXPECT_TRUE(username_element_.Value().IsEmpty()); | 1433 CheckUsernameSelection(0, 0); | 
| 1387 EXPECT_TRUE(username_element_.SuggestedValue().IsEmpty()); | 1434 } | 
| 1388 EXPECT_FALSE(username_element_.IsAutofilled()); | |
| 1389 EXPECT_TRUE(password_element_.Value().IsEmpty()); | |
| 1390 EXPECT_TRUE(password_element_.SuggestedValue().IsEmpty()); | |
| 1391 EXPECT_FALSE(password_element_.IsAutofilled()); | |
| 1392 CheckUsernameSelection(0, 0); | |
| 1393 } | 1435 } | 
| 1394 | 1436 | 
| 1395 // Tests that logging is off by default. | 1437 // Tests that logging is off by default. | 
| 1396 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) { | 1438 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) { | 
| 1397 SendVisiblePasswordForms(); | 1439 SendVisiblePasswordForms(); | 
| 1398 base::RunLoop().RunUntilIdle(); | 1440 base::RunLoop().RunUntilIdle(); | 
| 1399 EXPECT_FALSE(fake_driver_.called_record_save_progress()); | 1441 EXPECT_FALSE(fake_driver_.called_record_save_progress()); | 
| 1400 } | 1442 } | 
| 1401 | 1443 | 
| 1402 // Test that logging can be turned on by a message. | 1444 // Test that logging can be turned on by a message. | 
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2167 | 2209 | 
| 2168 // Neither field should have been autocompleted. | 2210 // Neither field should have been autocompleted. | 
| 2169 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 2211 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 
| 2170 | 2212 | 
| 2171 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 2213 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 
| 2172 username_element_, ASCIIToUTF16(kAliceUsername), | 2214 username_element_, ASCIIToUTF16(kAliceUsername), | 
| 2173 ASCIIToUTF16(kAlicePassword))); | 2215 ASCIIToUTF16(kAlicePassword))); | 
| 2174 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 2216 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 
| 2175 } | 2217 } | 
| 2176 | 2218 | 
| 2177 // Tests that a password change form is properly filled with the password when | 2219 // Tests that a password change form is properly filled with the | 
| 2178 // the user click on the password field. | 2220 // username/password when the user clicks on the password field. | 
| 2179 TEST_F(PasswordAutofillAgentTest, | 2221 TEST_F(PasswordAutofillAgentTest, | 
| 2180 FillSuggestionPasswordChangeFormsOnlyPassword) { | 2222 FillSuggestionPasswordChangeFormsOnlyPassword) { | 
| 
kolos1
2017/05/26 12:09:10
I believe we should change the name of test.
 
pkalinnikov
2017/05/26 16:36:51
Seems like I can merge it to the previous test. Do
 
kolos1
2017/05/29 09:17:11
Looks good.
 | |
| 2181 LoadHTML(kPasswordChangeFormHTML); | 2223 LoadHTML(kPasswordChangeFormHTML); | 
| 2182 UpdateOriginForHTML(kPasswordChangeFormHTML); | 2224 UpdateOriginForHTML(kPasswordChangeFormHTML); | 
| 2183 UpdateUsernameAndPasswordElements(); | 2225 UpdateUsernameAndPasswordElements(); | 
| 2184 // Simulate the browser sending the login info, but set |wait_for_username| | 2226 // Simulate the browser sending the login info, but set |wait_for_username| | 
| 2185 // to prevent the form from being immediately filled. | 2227 // to prevent the form from being immediately filled. | 
| 2186 fill_data_.wait_for_username = true; | 2228 fill_data_.wait_for_username = true; | 
| 2187 fill_data_.is_possible_change_password_form = true; | 2229 fill_data_.is_possible_change_password_form = true; | 
| 2188 SimulateOnFillPasswordForm(fill_data_); | 2230 SimulateOnFillPasswordForm(fill_data_); | 
| 2189 | 2231 | 
| 2190 // Neither field should have been autocompleted. | 2232 // Neither field should have been autocompleted. | 
| 2191 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 2233 CheckTextFieldsDOMState(std::string(), false, std::string(), false); | 
| 2192 | 2234 | 
| 2193 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 2235 EXPECT_TRUE(password_autofill_agent_->FillSuggestion( | 
| 2194 password_element_, ASCIIToUTF16(kAliceUsername), | 2236 password_element_, ASCIIToUTF16(kAliceUsername), | 
| 2195 ASCIIToUTF16(kAlicePassword))); | 2237 ASCIIToUTF16(kAlicePassword))); | 
| 2196 CheckTextFieldsDOMState("", false, kAlicePassword, true); | 2238 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); | 
| 2197 } | 2239 } | 
| 2198 | 2240 | 
| 2199 // Tests that one user click on a username field is sufficient to bring up a | 2241 // Tests that one user click on a username field is sufficient to bring up a | 
| 2200 // credential suggestion popup on a change password form. | 2242 // credential suggestion popup on a change password form. | 
| 2201 TEST_F(PasswordAutofillAgentTest, | 2243 TEST_F(PasswordAutofillAgentTest, | 
| 2202 SuggestionsOnUsernameFieldOfChangePasswordForm) { | 2244 SuggestionsOnUsernameFieldOfChangePasswordForm) { | 
| 2203 LoadHTML(kPasswordChangeFormHTML); | 2245 LoadHTML(kPasswordChangeFormHTML); | 
| 2204 UpdateOriginForHTML(kPasswordChangeFormHTML); | 2246 UpdateOriginForHTML(kPasswordChangeFormHTML); | 
| 2205 UpdateUsernameAndPasswordElements(); | 2247 UpdateUsernameAndPasswordElements(); | 
| 2206 | 2248 | 
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2919 TEST_F(PasswordAutofillAgentTest, AutocompleteWhenPageUrlIsChanged) { | 2961 TEST_F(PasswordAutofillAgentTest, AutocompleteWhenPageUrlIsChanged) { | 
| 2920 // Simulate that JavaScript changes url. | 2962 // Simulate that JavaScript changes url. | 
| 2921 fill_data_.origin = GURL(fill_data_.origin.possibly_invalid_spec() + "/path"); | 2963 fill_data_.origin = GURL(fill_data_.origin.possibly_invalid_spec() + "/path"); | 
| 2922 | 2964 | 
| 2923 SimulateOnFillPasswordForm(fill_data_); | 2965 SimulateOnFillPasswordForm(fill_data_); | 
| 2924 | 2966 | 
| 2925 // The username and password should have been autocompleted. | 2967 // The username and password should have been autocompleted. | 
| 2926 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 2968 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); | 
| 2927 } | 2969 } | 
| 2928 } // namespace autofill | 2970 } // namespace autofill | 
| OLD | NEW |