OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |