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

Side by Side Diff: chrome/browser/password_manager/password_manager_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: Incorporated Vaclav'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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 <string> 5 #include <string>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/histogram_samples.h" 8 #include "base/metrics/histogram_samples.h"
9 #include "base/metrics/statistics_recorder.h" 9 #include "base/metrics/statistics_recorder.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 std::string fill_and_submit = 1484 std::string fill_and_submit =
1485 "should_delete_testform = false;" 1485 "should_delete_testform = false;"
1486 "document.getElementById('username_field').value = 'temp';" 1486 "document.getElementById('username_field').value = 'temp';"
1487 "document.getElementById('password_field').value = 'random';" 1487 "document.getElementById('password_field').value = 'random';"
1488 "document.getElementById('submit_button').click()"; 1488 "document.getElementById('submit_button').click()";
1489 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit)); 1489 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1490 observer.Wait(); 1490 observer.Wait();
1491 EXPECT_FALSE(prompt_observer->IsShowingPrompt()); 1491 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1492 } 1492 }
1493 1493
1494 // The password manager should distinguish forms with empty actions. After
1495 // successful login, the login form disappears, but the another one shouldn't be
1496 // recognized as the login form. The save prompt should appear.
1497 // Disabled on Mac and Android.
1498 // TODO(kolos) Turn on this when the update prompt will be implemented on Mac
1499 // and Android.
1500 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
1501 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1502 PromptForPushStateWhenFormWithEmptyActionDisappears) {
1503 NavigateToFile("/password/password_push_state.html");
1504
1505 NavigationObserver observer(WebContents());
1506 observer.set_quit_on_entry_committed(true);
1507 scoped_ptr<PromptObserver> prompt_observer(
1508 PromptObserver::Create(WebContents()));
1509 std::string fill_and_submit =
1510 "document.getElementById('ea_username_field').value = 'temp';"
1511 "document.getElementById('ea_password_field').value = 'random';"
1512 "document.getElementById('ea_submit_button').click()";
1513 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1514 observer.Wait();
1515 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1516 }
1517
1518 // Similar to the case above, but this time the form persists after
1519 // 'history.pushState()'. The password manager should find the login form even
1520 // if the action of the form is empty. Save password prompt should not show up.
1521 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1522 PromptForPushStateWhenFormWithEmptyActionPersists) {
1523 NavigateToFile("/password/password_push_state.html");
1524
1525 NavigationObserver observer(WebContents());
1526 observer.set_quit_on_entry_committed(true);
1527 scoped_ptr<PromptObserver> prompt_observer(
1528 PromptObserver::Create(WebContents()));
1529 std::string fill_and_submit =
1530 "should_delete_testform = false;"
1531 "document.getElementById('ea_username_field').value = 'temp';"
1532 "document.getElementById('ea_password_field').value = 'random';"
1533 "document.getElementById('ea_submit_button').click()";
1534 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1535 observer.Wait();
1536 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1537 }
1538 #endif // !OS_MACOSX && !OS_ANDROID
1539
1540 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, 1494 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1541 InFrameNavigationDoesNotClearPopupState) { 1495 InFrameNavigationDoesNotClearPopupState) {
1542 // Mock out the AutofillClient so we know how long to wait. Unfortunately 1496 // Mock out the AutofillClient so we know how long to wait. Unfortunately
1543 // there isn't otherwise a good even to wait on to verify that the popup 1497 // there isn't otherwise a good even to wait on to verify that the popup
1544 // would have been shown. 1498 // would have been shown.
1545 password_manager::ContentPasswordManagerDriverFactory* driver_factory = 1499 password_manager::ContentPasswordManagerDriverFactory* driver_factory =
1546 password_manager::ContentPasswordManagerDriverFactory::FromWebContents( 1500 password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
1547 WebContents()); 1501 WebContents());
1548 ObservingAutofillClient observing_autofill_client; 1502 ObservingAutofillClient observing_autofill_client;
1549 driver_factory->TestingSetDriverForFrame( 1503 driver_factory->TestingSetDriverForFrame(
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 prompt_observer->AcceptUpdatePrompt(stored_form); 2160 prompt_observer->AcceptUpdatePrompt(stored_form);
2207 // Spin the message loop to make sure the password store had a chance to 2161 // Spin the message loop to make sure the password store had a chance to
2208 // update the password. 2162 // update the password.
2209 base::RunLoop run_loop; 2163 base::RunLoop run_loop;
2210 run_loop.RunUntilIdle(); 2164 run_loop.RunUntilIdle();
2211 CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16("temp"), 2165 CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16("temp"),
2212 base::ASCIIToUTF16("new_pw")); 2166 base::ASCIIToUTF16("new_pw"));
2213 } 2167 }
2214 #endif 2168 #endif
2215 2169
2170 // Test whether the password form with the username and password fields having
2171 // ambiguity in id attribute gets autofilled correctly.
2172 IN_PROC_BROWSER_TEST_F(
2173 PasswordManagerBrowserTestBase,
2174 AutofillSuggetionsForPasswordFormWithAmbiguousIdAttribute) {
2175 // At first let us save credentials to the PasswordManager.
2176 scoped_refptr<password_manager::PasswordStore> password_store =
2177 PasswordStoreFactory::GetForProfile(browser()->profile(),
2178 ServiceAccessType::IMPLICIT_ACCESS);
2179 autofill::PasswordForm login_form;
2180 login_form.signon_realm = embedded_test_server()->base_url().spec();
2181 login_form.action = embedded_test_server()->GetURL("/password/done.html");
2182 login_form.username_value = base::ASCIIToUTF16("myusername");
2183 login_form.password_value = base::ASCIIToUTF16("mypassword");
2184 password_store->AddLogin(login_form);
2185
2186 // Logins are added asynchronously to the password store. Spin the message
2187 // loop to make sure the |password_store| had a chance to store the
2188 // |login_form|.
2189 base::RunLoop run_loop;
2190 run_loop.RunUntilIdle();
2191
2192 // Now, navigate to the password form having ambiguous Ids for username and
2193 // password fields and verify whether username and password is autofilled.
2194 NavigateToFile("/password/ambiguous_password_form.html");
2195
2196 // Let the user interact with the page, so that DOM gets modification events,
2197 // needed for autofilling fields.
2198 content::SimulateMouseClickAt(
2199 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
2200
2201 std::string get_username =
2202 "window.domAutomationController.send("
2203 " document.getElementById('ambiguous_form').elements[0].value);";
2204 std::string actual_username;
2205 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2206 RenderViewHost(), get_username, &actual_username));
2207 EXPECT_EQ("myusername", actual_username);
2208
2209 std::string get_password =
2210 "window.domAutomationController.send("
2211 " document.getElementById('ambiguous_form').elements[1].value);";
2212 std::string actual_password;
2213 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2214 RenderViewHost(), get_password, &actual_password));
2215 EXPECT_EQ("mypassword", actual_password);
2216 }
2217
2218 // Test whether the password form having username and password fields without
2219 // name and id attribute gets autofilled correctly.
2220 IN_PROC_BROWSER_TEST_F(
2221 PasswordManagerBrowserTestBase,
2222 AutofillSuggetionsForPasswordFormWithoutNameOrIdAttribute) {
2223 // At first let us save credentials to the PasswordManager.
2224 scoped_refptr<password_manager::PasswordStore> password_store =
2225 PasswordStoreFactory::GetForProfile(browser()->profile(),
2226 ServiceAccessType::IMPLICIT_ACCESS);
2227 autofill::PasswordForm login_form;
2228 login_form.signon_realm = embedded_test_server()->base_url().spec();
2229 login_form.action = embedded_test_server()->GetURL("/password/done.html");
2230 login_form.username_value = base::ASCIIToUTF16("myusername");
2231 login_form.password_value = base::ASCIIToUTF16("mypassword");
2232 password_store->AddLogin(login_form);
2233
2234 // Logins are added asynchronously to the password store. Spin the message
2235 // loop to make sure the |password_store| had a chance to store the
2236 // |login_form|.
2237 base::RunLoop run_loop;
2238 run_loop.RunUntilIdle();
2239
2240 // Now, navigate to the password form having no Ids for username and password
2241 // fields and verify whether username and password is autofilled.
2242 NavigateToFile("/password/ambiguous_password_form.html");
2243
2244 // Let the user interact with the page, so that DOM gets modification events,
2245 // needed for autofilling fields.
2246 content::SimulateMouseClickAt(
2247 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
2248
2249 std::string get_username =
2250 "window.domAutomationController.send("
2251 " document.getElementById('no_name_id_form').elements[0].value);";
2252 std::string actual_username;
2253 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2254 RenderViewHost(), get_username, &actual_username));
2255 EXPECT_EQ("myusername", actual_username);
2256
2257 std::string get_password =
2258 "window.domAutomationController.send("
2259 " document.getElementById('no_name_id_form').elements[1].value);";
2260 std::string actual_password;
2261 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2262 RenderViewHost(), get_password, &actual_password));
2263 EXPECT_EQ("mypassword", actual_password);
2264 }
2265
2266 // Test whether the change password form having username and password fields
2267 // without name and id attribute gets autofilled correctly.
2268 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
2269 AutofillSuggetionsForChangePwdWithEmptyNames) {
2270 // At first let us save credentials to the PasswordManager.
2271 scoped_refptr<password_manager::PasswordStore> password_store =
2272 PasswordStoreFactory::GetForProfile(browser()->profile(),
2273 ServiceAccessType::IMPLICIT_ACCESS);
2274 autofill::PasswordForm login_form;
2275 login_form.signon_realm = embedded_test_server()->base_url().spec();
2276 login_form.action = embedded_test_server()->GetURL("/password/done.html");
2277 login_form.username_value = base::ASCIIToUTF16("myusername");
2278 login_form.password_value = base::ASCIIToUTF16("mypassword");
2279 password_store->AddLogin(login_form);
2280
2281 // Logins are added asynchronously to the password store. Spin the message
2282 // loop to make sure the |password_store| had a chance to store the
2283 // |login_form|.
2284 base::RunLoop run_loop;
2285 run_loop.RunUntilIdle();
2286
2287 // Now, navigate to the password form having no Ids for username and password
2288 // fields and verify whether username and password is autofilled.
2289 NavigateToFile("/password/ambiguous_password_form.html");
2290
2291 // Let the user interact with the page, so that DOM gets modification events,
2292 // needed for autofilling fields.
2293 content::SimulateMouseClickAt(
2294 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
2295
2296 std::string get_username =
2297 "window.domAutomationController.send("
2298 " document.getElementById("
2299 " 'change_pwd_but_no_autocomplete').elements[0].value);";
2300 std::string actual_username;
2301 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2302 RenderViewHost(), get_username, &actual_username));
2303 EXPECT_EQ("myusername", actual_username);
2304
2305 std::string get_password =
2306 "window.domAutomationController.send("
2307 " document.getElementById("
2308 " 'change_pwd_but_no_autocomplete').elements[1].value);";
2309 std::string actual_password;
2310 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2311 RenderViewHost(), get_password, &actual_password));
2312 EXPECT_EQ("mypassword", actual_password);
2313
2314 std::string get_new_password =
2315 "window.domAutomationController.send("
2316 " document.getElementById("
2317 " 'change_pwd_but_no_autocomplete').elements[2].value);";
2318 std::string new_password;
2319 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2320 RenderViewHost(), get_new_password, &new_password));
2321 EXPECT_EQ("", new_password);
2322 }
2323
2324 // Test whether the change password form having username and password fields
2325 // with empty names but having |autocomplete='current-password'| gets autofilled
2326 // correctly.
2327 IN_PROC_BROWSER_TEST_F(
2328 PasswordManagerBrowserTestBase,
2329 AutofillSuggetionsForChangePwdWithEmptyNamesAndAutocomplete) {
2330 // At first let us save credentials to the PasswordManager.
2331 scoped_refptr<password_manager::PasswordStore> password_store =
2332 PasswordStoreFactory::GetForProfile(browser()->profile(),
2333 ServiceAccessType::IMPLICIT_ACCESS);
2334 autofill::PasswordForm login_form;
2335 login_form.signon_realm = embedded_test_server()->base_url().spec();
2336 login_form.action = embedded_test_server()->GetURL("/password/done.html");
2337 login_form.username_value = base::ASCIIToUTF16("myusername");
2338 login_form.password_value = base::ASCIIToUTF16("mypassword");
2339 password_store->AddLogin(login_form);
2340
2341 // Logins are added asynchronously to the password store. Spin the message
2342 // loop to make sure the |password_store| had a chance to store the
2343 // |login_form|.
2344 base::RunLoop run_loop;
2345 run_loop.RunUntilIdle();
2346
2347 // Now, navigate to the password form having no Ids for username and password
2348 // fields and verify whether username and password is autofilled.
2349 NavigateToFile("/password/ambiguous_password_form.html");
2350
2351 // Let the user interact with the page, so that DOM gets modification events,
2352 // needed for autofilling fields.
2353 content::SimulateMouseClickAt(
2354 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
2355
2356 std::string get_username =
2357 "window.domAutomationController.send("
2358 " document.getElementById('change_pwd').elements[0].value);";
2359 std::string actual_username;
2360 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2361 RenderViewHost(), get_username, &actual_username));
2362 EXPECT_EQ("myusername", actual_username);
2363
2364 std::string get_password =
2365 "window.domAutomationController.send("
2366 " document.getElementById('change_pwd').elements[1].value);";
2367 std::string actual_password;
2368 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2369 RenderViewHost(), get_password, &actual_password));
2370 EXPECT_EQ("mypassword", actual_password);
2371
2372 std::string get_new_password =
2373 "window.domAutomationController.send("
2374 " document.getElementById('change_pwd').elements[2].value);";
2375 std::string new_password;
2376 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2377 RenderViewHost(), get_new_password, &new_password));
2378 EXPECT_EQ("", new_password);
2379 }
2380
2381 // Test whether the change password form having username and password fields
2382 // with empty names but having only new password fields having
2383 // |autocomplete='new-password'| atrribute do not get autofilled.
2384 IN_PROC_BROWSER_TEST_F(
2385 PasswordManagerBrowserTestBase,
2386 AutofillSuggetionsForChangePwdWithEmptyNamesButOnlyNewPwdField) {
2387 // At first let us save credentials to the PasswordManager.
2388 scoped_refptr<password_manager::PasswordStore> password_store =
2389 PasswordStoreFactory::GetForProfile(browser()->profile(),
2390 ServiceAccessType::IMPLICIT_ACCESS);
2391 autofill::PasswordForm login_form;
2392 login_form.signon_realm = embedded_test_server()->base_url().spec();
2393 login_form.action = embedded_test_server()->GetURL("/password/done.html");
2394 login_form.username_value = base::ASCIIToUTF16("myusername");
2395 login_form.password_value = base::ASCIIToUTF16("mypassword");
2396 password_store->AddLogin(login_form);
2397
2398 // Logins are added asynchronously to the password store. Spin the message
2399 // loop to make sure the |password_store| had a chance to store the
2400 // |login_form|.
2401 base::RunLoop run_loop;
2402 run_loop.RunUntilIdle();
2403
2404 // Now, navigate to the password form having no Ids for username and password
2405 // fields and verify whether username and password is autofilled.
2406 NavigateToFile("/password/ambiguous_password_form.html");
2407
2408 // Let the user interact with the page, so that DOM gets modification events,
2409 // needed for autofilling fields.
2410 content::SimulateMouseClickAt(
2411 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
2412
2413 std::string get_username =
2414 "window.domAutomationController.send("
2415 " document.getElementById("
2416 " 'change_pwd_but_no_old_pwd').elements[0].value);";
2417 std::string actual_username;
2418 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2419 RenderViewHost(), get_username, &actual_username));
2420 EXPECT_EQ("", actual_username);
2421
2422 std::string get_new_password =
2423 "window.domAutomationController.send("
2424 " document.getElementById("
2425 " 'change_pwd_but_no_old_pwd').elements[1].value);";
2426 std::string new_password;
2427 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2428 RenderViewHost(), get_new_password, &new_password));
2429 EXPECT_EQ("", new_password);
2430
2431 std::string get_retype_password =
2432 "window.domAutomationController.send("
2433 " document.getElementById("
2434 " 'change_pwd_but_no_old_pwd').elements[2].value);";
2435 std::string retyped_password;
2436 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
2437 RenderViewHost(), get_retype_password, &retyped_password));
2438 EXPECT_EQ("", retyped_password);
2439 }
2440
2216 } // namespace password_manager 2441 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698