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

Side by Side Diff: chrome/renderer/autofill/password_autofill_agent_browsertest.cc

Issue 2865233003: Use an MutationObserver to check when a password form disappears after XHR (Closed)
Patch Set: tests Created 3 years, 7 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
« no previous file with comments | « no previous file | components/autofill/content/DEPS » ('j') | components/autofill/content/DEPS » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 ExpectFieldPropertiesMasks(PasswordFormSubmitted, expected_properties_masks); 1667 ExpectFieldPropertiesMasks(PasswordFormSubmitted, expected_properties_masks);
1668 } 1668 }
1669 1669
1670 TEST_F(PasswordAutofillAgentTest, RememberFieldPropertiesOnInPageNavigation) { 1670 TEST_F(PasswordAutofillAgentTest, RememberFieldPropertiesOnInPageNavigation) {
1671 LoadHTML(kNoFormHTML); 1671 LoadHTML(kNoFormHTML);
1672 UpdateUsernameAndPasswordElements(); 1672 UpdateUsernameAndPasswordElements();
1673 1673
1674 SimulateUsernameChange("Bob"); 1674 SimulateUsernameChange("Bob");
1675 SimulatePasswordChange("mypassword"); 1675 SimulatePasswordChange("mypassword");
1676 1676
1677 username_element_.SetAttribute("style", "display:none;"); 1677 std::string hide_elements =
1678 password_element_.SetAttribute("style", "display:none;"); 1678 "var password = document.getElementById('password');"
jochen (gone - plz use gerrit) 2017/05/10 11:45:41 These methods don't actually spin Blink's message
1679 "password.style = 'display:none';"
1680 "var username = document.getElementById('username');"
1681 "username.style = 'display:none';";
1682 ExecuteJavaScriptForTests(hide_elements.c_str());
1679 1683
1680 password_autofill_agent_->AJAXSucceeded(); 1684 password_autofill_agent_->AJAXSucceeded();
1681 1685
1682 std::map<base::string16, FieldPropertiesMask> expected_properties_masks; 1686 std::map<base::string16, FieldPropertiesMask> expected_properties_masks;
1683 expected_properties_masks[ASCIIToUTF16("username")] = 1687 expected_properties_masks[ASCIIToUTF16("username")] =
1684 FieldPropertiesFlags::USER_TYPED; 1688 FieldPropertiesFlags::USER_TYPED;
1685 expected_properties_masks[ASCIIToUTF16("password")] = 1689 expected_properties_masks[ASCIIToUTF16("password")] =
1686 FieldPropertiesFlags::USER_TYPED | FieldPropertiesFlags::HAD_FOCUS; 1690 FieldPropertiesFlags::USER_TYPED | FieldPropertiesFlags::HAD_FOCUS;
1687 1691
1688 ExpectFieldPropertiesMasks(PasswordFormInPageNavigation, 1692 ExpectFieldPropertiesMasks(PasswordFormInPageNavigation,
1689 expected_properties_masks); 1693 expected_properties_masks);
1690 } 1694 }
1691 1695
1696 TEST_F(PasswordAutofillAgentTest, RememberFieldPropertiesOnInPageNavigation_2) {
1697 LoadHTML(kNoFormHTML);
1698 UpdateUsernameAndPasswordElements();
1699
1700 SimulateUsernameChange("Bob");
1701 SimulatePasswordChange("mypassword");
1702
1703 password_autofill_agent_->AJAXSucceeded();
1704
1705 std::string hide_elements =
1706 "var password = document.getElementById('password');"
1707 "password.style = 'display:none';"
1708 "var username = document.getElementById('username');"
1709 "username.style = 'display:none';";
1710 ExecuteJavaScriptForTests(hide_elements.c_str());
1711
1712 base::RunLoop().RunUntilIdle();
1713
1714 std::map<base::string16, FieldPropertiesMask> expected_properties_masks;
1715 expected_properties_masks[ASCIIToUTF16("username")] =
1716 FieldPropertiesFlags::USER_TYPED;
1717 expected_properties_masks[ASCIIToUTF16("password")] =
1718 FieldPropertiesFlags::USER_TYPED | FieldPropertiesFlags::HAD_FOCUS;
1719
1720 ExpectFieldPropertiesMasks(PasswordFormInPageNavigation,
1721 expected_properties_masks);
1722 }
1723
1692 // The username/password is autofilled by password manager then just before 1724 // The username/password is autofilled by password manager then just before
1693 // sending the form off, a script changes them. This test checks that 1725 // sending the form off, a script changes them. This test checks that
1694 // PasswordAutofillAgent can still get the username and the password autofilled. 1726 // PasswordAutofillAgent can still get the username and the password autofilled.
1695 TEST_F(PasswordAutofillAgentTest, 1727 TEST_F(PasswordAutofillAgentTest,
1696 RememberLastAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) { 1728 RememberLastAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1697 SimulateOnFillPasswordForm(fill_data_); 1729 SimulateOnFillPasswordForm(fill_data_);
1698 1730
1699 // Simulate that the username and the password value was changed by the 1731 // Simulate that the username and the password value was changed by the
1700 // site's JavaScript before submit. 1732 // site's JavaScript before submit.
1701 username_element_.SetValue(WebString("new username")); 1733 username_element_.SetValue(WebString("new username"));
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 CheckTextFieldsState("", true, kAlicePassword, true); 2269 CheckTextFieldsState("", true, kAlicePassword, true);
2238 } 2270 }
2239 2271
2240 TEST_F(PasswordAutofillAgentTest, NoForm_PromptForAJAXSubmitWithoutNavigation) { 2272 TEST_F(PasswordAutofillAgentTest, NoForm_PromptForAJAXSubmitWithoutNavigation) {
2241 LoadHTML(kNoFormHTML); 2273 LoadHTML(kNoFormHTML);
2242 UpdateUsernameAndPasswordElements(); 2274 UpdateUsernameAndPasswordElements();
2243 2275
2244 SimulateUsernameChange("Bob"); 2276 SimulateUsernameChange("Bob");
2245 SimulatePasswordChange("mypassword"); 2277 SimulatePasswordChange("mypassword");
2246 2278
2247 username_element_.SetAttribute("style", "display:none;"); 2279 std::string hide_elements =
2248 password_element_.SetAttribute("style", "display:none;"); 2280 "var password = document.getElementById('password');"
2281 "password.style = 'display:none';"
2282 "var username = document.getElementById('username');"
2283 "username.style = 'display:none';";
2284 ExecuteJavaScriptForTests(hide_elements.c_str());
2249 2285
2250 password_autofill_agent_->AJAXSucceeded(); 2286 password_autofill_agent_->AJAXSucceeded();
2251 2287
2252 ExpectInPageNavigationWithUsernameAndPasswords("Bob", "mypassword", ""); 2288 ExpectInPageNavigationWithUsernameAndPasswords("Bob", "mypassword", "");
2253 } 2289 }
2254 2290
2255 TEST_F(PasswordAutofillAgentTest, 2291 TEST_F(PasswordAutofillAgentTest,
2292 NoForm_PromptForAJAXSubmitWithoutNavigation_2) {
2293 LoadHTML(kNoFormHTML);
2294 UpdateUsernameAndPasswordElements();
2295
2296 SimulateUsernameChange("Bob");
2297 SimulatePasswordChange("mypassword");
2298
2299 password_autofill_agent_->AJAXSucceeded();
2300
2301 std::string hide_elements =
2302 "var password = document.getElementById('password');"
2303 "password.style = 'display:none';"
2304 "var username = document.getElementById('username');"
2305 "username.style = 'display:none';";
2306 ExecuteJavaScriptForTests(hide_elements.c_str());
2307
2308 base::RunLoop().RunUntilIdle();
2309
2310 ExpectInPageNavigationWithUsernameAndPasswords("Bob", "mypassword", "");
2311 }
2312
2313 TEST_F(PasswordAutofillAgentTest,
2256 NoForm_NoPromptForAJAXSubmitWithoutNavigationAndElementsVisible) { 2314 NoForm_NoPromptForAJAXSubmitWithoutNavigationAndElementsVisible) {
2257 LoadHTML(kNoFormHTML); 2315 LoadHTML(kNoFormHTML);
2258 UpdateUsernameAndPasswordElements(); 2316 UpdateUsernameAndPasswordElements();
2259 2317
2260 SimulateUsernameChange("Bob"); 2318 SimulateUsernameChange("Bob");
2261 SimulatePasswordChange("mypassword"); 2319 SimulatePasswordChange("mypassword");
2262 2320
2263 password_autofill_agent_->AJAXSucceeded(); 2321 password_autofill_agent_->AJAXSucceeded();
2264 2322
2265 base::RunLoop().RunUntilIdle(); 2323 base::RunLoop().RunUntilIdle();
(...skipping 12 matching lines...) Expand all
2278 2336
2279 UpdateUsernameAndPasswordElements(); 2337 UpdateUsernameAndPasswordElements();
2280 WebElement captcha_element = GetMainFrame()->GetDocument().GetElementById( 2338 WebElement captcha_element = GetMainFrame()->GetDocument().GetElementById(
2281 WebString::FromUTF8("captcha")); 2339 WebString::FromUTF8("captcha"));
2282 ASSERT_FALSE(captcha_element.IsNull()); 2340 ASSERT_FALSE(captcha_element.IsNull());
2283 2341
2284 SimulateUsernameChange("Bob"); 2342 SimulateUsernameChange("Bob");
2285 SimulatePasswordChange("mypassword"); 2343 SimulatePasswordChange("mypassword");
2286 2344
2287 // Simulate captcha element show up right before AJAX completed. 2345 // Simulate captcha element show up right before AJAX completed.
2288 captcha_element.SetAttribute("style", "display:inline;"); 2346 std::string show_captcha =
2347 "var captcha = document.getElementById('captcha');"
2348 "captcha.style = 'display:inline';";
2349 ExecuteJavaScriptForTests(show_captcha.c_str());
2289 password_autofill_agent_->AJAXSucceeded(); 2350 password_autofill_agent_->AJAXSucceeded();
2290 2351
2291 base::RunLoop().RunUntilIdle(); 2352 base::RunLoop().RunUntilIdle();
2292 EXPECT_FALSE(fake_driver_.called_inpage_navigation()); 2353 EXPECT_FALSE(fake_driver_.called_inpage_navigation());
2293 EXPECT_FALSE(fake_driver_.called_password_form_submitted()); 2354 EXPECT_FALSE(fake_driver_.called_password_form_submitted());
2294 } 2355 }
2295 2356
2357 TEST_F(PasswordAutofillAgentTest,
2358 NoForm_NoPromptForAJAXSubmitWithoutNavigationAndNewElementAppeared_2) {
2359 const char kNoFormHTMLWithHiddenField[] =
2360 "<INPUT type='text' id='username'/>"
2361 "<INPUT type='password' id='password'/>"
2362 "<INPUT type='text' id='captcha' style='display:none'/>";
2363 LoadHTML(kNoFormHTMLWithHiddenField);
2364
2365 UpdateUsernameAndPasswordElements();
2366 WebElement captcha_element = GetMainFrame()->GetDocument().GetElementById(
2367 WebString::FromUTF8("captcha"));
2368 ASSERT_FALSE(captcha_element.IsNull());
2369
2370 SimulateUsernameChange("Bob");
2371 SimulatePasswordChange("mypassword");
2372
2373 password_autofill_agent_->AJAXSucceeded();
2374
2375 // Simulate captcha element show up right after AJAX completed.
2376 std::string show_captcha =
2377 "var captcha = document.getElementById('captcha');"
2378 "captcha.style = 'display:inline';";
2379 ExecuteJavaScriptForTests(show_captcha.c_str());
2380 base::RunLoop().RunUntilIdle();
2381
2382 EXPECT_FALSE(fake_driver_.called_inpage_navigation());
2383 EXPECT_FALSE(fake_driver_.called_password_form_submitted());
2384 }
2385
2296 // Tests that no save promt is shown when a form with empty action URL is 2386 // Tests that no save promt is shown when a form with empty action URL is
2297 // changed and AJAX completed but the form is still visible. 2387 // changed and AJAX completed but the form is still visible.
2298 TEST_F(PasswordAutofillAgentTest, 2388 TEST_F(PasswordAutofillAgentTest,
2299 NoAction_NoPromptForAJAXSubmitWithoutNavigationAndNewElementAppeared) { 2389 NoAction_NoPromptForAJAXSubmitWithoutNavigationAndNewElementAppeared) {
2300 // Form without an action URL. 2390 // Form without an action URL.
2301 const char kHTMLWithHiddenField[] = 2391 const char kHTMLWithHiddenField[] =
2302 "<FORM name='LoginTestForm'>" 2392 "<FORM name='LoginTestForm'>"
2303 " <INPUT type='text' id='username'/>" 2393 " <INPUT type='text' id='username'/>"
2304 " <INPUT type='password' id='password'/>" 2394 " <INPUT type='password' id='password'/>"
2305 " <INPUT type='text' id='captcha' style='display:none'/>" 2395 " <INPUT type='text' id='captcha' style='display:none'/>"
(...skipping 12 matching lines...) Expand all
2318 2408
2319 // Simulate captcha element show up right before AJAX completed. 2409 // Simulate captcha element show up right before AJAX completed.
2320 captcha_element.SetAttribute("style", "display:inline;"); 2410 captcha_element.SetAttribute("style", "display:inline;");
2321 password_autofill_agent_->AJAXSucceeded(); 2411 password_autofill_agent_->AJAXSucceeded();
2322 2412
2323 base::RunLoop().RunUntilIdle(); 2413 base::RunLoop().RunUntilIdle();
2324 EXPECT_FALSE(fake_driver_.called_inpage_navigation()); 2414 EXPECT_FALSE(fake_driver_.called_inpage_navigation());
2325 EXPECT_FALSE(fake_driver_.called_password_form_submitted()); 2415 EXPECT_FALSE(fake_driver_.called_password_form_submitted());
2326 } 2416 }
2327 2417
2418 TEST_F(PasswordAutofillAgentTest,
2419 NoAction_NoPromptForAJAXSubmitWithoutNavigationAndNewElementAppeared_2) {
2420 // Form without an action URL.
2421 const char kHTMLWithHiddenField[] =
2422 "<FORM name='LoginTestForm'>"
2423 " <INPUT type='text' id='username'/>"
2424 " <INPUT type='password' id='password'/>"
2425 " <INPUT type='text' id='captcha' style='display:none'/>"
2426 " <INPUT type='submit' value='Login'/>"
2427 "</FORM>";
2428 // Set the valid URL so the form action URL can be generated properly.
2429 LoadHTMLWithUrlOverride(kHTMLWithHiddenField, "https://www.example.com");
2430
2431 UpdateUsernameAndPasswordElements();
2432 WebElement captcha_element = GetMainFrame()->GetDocument().GetElementById(
2433 WebString::FromUTF8("captcha"));
2434 ASSERT_FALSE(captcha_element.IsNull());
2435
2436 SimulateUsernameChange("Bob");
2437 SimulatePasswordChange("mypassword");
2438
2439 password_autofill_agent_->AJAXSucceeded();
2440
2441 // Simulate captcha element show up right after AJAX completed.
2442 captcha_element.SetAttribute("style", "display:inline;");
2443
2444 base::RunLoop().RunUntilIdle();
2445 EXPECT_FALSE(fake_driver_.called_inpage_navigation());
2446 EXPECT_FALSE(fake_driver_.called_password_form_submitted());
2447 }
2448
2328 // Tests that credential suggestions are autofilled on a password (and change 2449 // Tests that credential suggestions are autofilled on a password (and change
2329 // password) forms having either ambiguous or empty name. 2450 // password) forms having either ambiguous or empty name.
2330 TEST_F(PasswordAutofillAgentTest, 2451 TEST_F(PasswordAutofillAgentTest,
2331 SuggestionsOnFormContainingAmbiguousOrEmptyNames) { 2452 SuggestionsOnFormContainingAmbiguousOrEmptyNames) {
2332 const char kEmpty[] = ""; 2453 const char kEmpty[] = "";
2333 const char kDummyUsernameField[] = "anonymous_username"; 2454 const char kDummyUsernameField[] = "anonymous_username";
2334 const char kDummyPasswordField[] = "anonymous_password"; 2455 const char kDummyPasswordField[] = "anonymous_password";
2335 const char kFormContainsEmptyNamesHTML[] = 2456 const char kFormContainsEmptyNamesHTML[] =
2336 "<FORM name='WithoutNameIdForm' action='http://www.bidule.com' >" 2457 "<FORM name='WithoutNameIdForm' action='http://www.bidule.com' >"
2337 " <INPUT type='text' placeholder='username'/>" 2458 " <INPUT type='text' placeholder='username'/>"
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 TEST_F(PasswordAutofillAgentTest, 2649 TEST_F(PasswordAutofillAgentTest,
2529 UsernameChangedAfterPasswordInput_InPageNavigation) { 2650 UsernameChangedAfterPasswordInput_InPageNavigation) {
2530 LoadHTML(kNoFormHTML); 2651 LoadHTML(kNoFormHTML);
2531 UpdateUsernameAndPasswordElements(); 2652 UpdateUsernameAndPasswordElements();
2532 2653
2533 SimulateUsernameChange("Bob"); 2654 SimulateUsernameChange("Bob");
2534 SimulatePasswordChange("mypassword"); 2655 SimulatePasswordChange("mypassword");
2535 SimulateUsernameChange("Alice"); 2656 SimulateUsernameChange("Alice");
2536 2657
2537 // Hide form elements to simulate successful login. 2658 // Hide form elements to simulate successful login.
2538 username_element_.SetAttribute("style", "display:none;"); 2659 std::string hide_elements =
2539 password_element_.SetAttribute("style", "display:none;"); 2660 "var password = document.getElementById('password');"
2661 "password.style = 'display:none';"
2662 "var username = document.getElementById('username');"
2663 "username.style = 'display:none';";
2664 ExecuteJavaScriptForTests(hide_elements.c_str());
2540 2665
2541 password_autofill_agent_->AJAXSucceeded(); 2666 password_autofill_agent_->AJAXSucceeded();
2542 2667
2543 ExpectInPageNavigationWithUsernameAndPasswords("Alice", "mypassword", ""); 2668 ExpectInPageNavigationWithUsernameAndPasswords("Alice", "mypassword", "");
2544 } 2669 }
2545 2670
2671 TEST_F(PasswordAutofillAgentTest,
2672 UsernameChangedAfterPasswordInput_InPageNavigation_2) {
2673 LoadHTML(kNoFormHTML);
2674 UpdateUsernameAndPasswordElements();
2675
2676 SimulateUsernameChange("Bob");
2677 SimulatePasswordChange("mypassword");
2678 SimulateUsernameChange("Alice");
2679
2680 password_autofill_agent_->AJAXSucceeded();
2681
2682 // Hide form elements to simulate successful login.
2683 std::string hide_elements =
2684 "var password = document.getElementById('password');"
2685 "password.style = 'display:none';"
2686 "var username = document.getElementById('username');"
2687 "username.style = 'display:none';";
2688 ExecuteJavaScriptForTests(hide_elements.c_str());
2689 base::RunLoop().RunUntilIdle();
2690
2691 ExpectInPageNavigationWithUsernameAndPasswords("Alice", "mypassword", "");
2692 }
2693
2546 TEST_F(PasswordAutofillAgentTest, 2694 TEST_F(PasswordAutofillAgentTest,
2547 UsernameChangedAfterPasswordInput_FormSubmitted) { 2695 UsernameChangedAfterPasswordInput_FormSubmitted) {
2548 SimulateUsernameChange("Bob"); 2696 SimulateUsernameChange("Bob");
2549 SimulatePasswordChange("mypassword"); 2697 SimulatePasswordChange("mypassword");
2550 SimulateUsernameChange("Alice"); 2698 SimulateUsernameChange("Alice");
2551 2699
2552 static_cast<content::RenderFrameObserver*>(password_autofill_agent_) 2700 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
2553 ->WillSendSubmitEvent(username_element_.Form()); 2701 ->WillSendSubmitEvent(username_element_.Form());
2554 static_cast<content::RenderFrameObserver*>(password_autofill_agent_) 2702 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
2555 ->WillSubmitForm(username_element_.Form()); 2703 ->WillSubmitForm(username_element_.Form());
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 2882
2735 // Navigate to another page and click on username field, 2883 // Navigate to another page and click on username field,
2736 // CheckSafeBrowsingReputation() should be triggered again. 2884 // CheckSafeBrowsingReputation() should be triggered again.
2737 LoadHTML(kFormHTML); 2885 LoadHTML(kFormHTML);
2738 SimulateElementClick(kUsernameName); 2886 SimulateElementClick(kUsernameName);
2739 base::RunLoop().RunUntilIdle(); 2887 base::RunLoop().RunUntilIdle();
2740 EXPECT_EQ(2, fake_driver_.called_check_safe_browsing_reputation_cnt()); 2888 EXPECT_EQ(2, fake_driver_.called_check_safe_browsing_reputation_cnt());
2741 } 2889 }
2742 #endif 2890 #endif
2743 } // namespace autofill 2891 } // namespace autofill
OLDNEW
« no previous file with comments | « no previous file | components/autofill/content/DEPS » ('j') | components/autofill/content/DEPS » ('J')

Powered by Google App Engine
This is Rietveld 408576698