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

Side by Side Diff: chrome/browser/password_manager/password_manager_browsertest.cc

Issue 316163003: Fix the flaky PasswordManagerBrowserTest.PasswordValueAccessible test (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make waiting explicit Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/strings/stringprintf.h"
10 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/infobars/infobar_service.h" 12 #include "chrome/browser/infobars/infobar_service.h"
12 #include "chrome/browser/password_manager/password_store_factory.h" 13 #include "chrome/browser/password_manager/password_store_factory.h"
13 #include "chrome/browser/password_manager/test_password_store_service.h" 14 #include "chrome/browser/password_manager/test_password_store_service.h"
14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h" 16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/common/chrome_version_info.h" 17 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/test/base/in_process_browser_test.h" 18 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chrome/test/base/test_switches.h" 19 #include "chrome/test/base/test_switches.h"
19 #include "chrome/test/base/ui_test_utils.h" 20 #include "chrome/test/base/ui_test_utils.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 167 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
167 168
168 ASSERT_FALSE(CommandLine::ForCurrentProcess()->HasSwitch( 169 ASSERT_FALSE(CommandLine::ForCurrentProcess()->HasSwitch(
169 password_manager::switches::kEnableAutomaticPasswordSaving)); 170 password_manager::switches::kEnableAutomaticPasswordSaving));
170 NavigationObserver observer(WebContents()); 171 NavigationObserver observer(WebContents());
171 GURL url = embedded_test_server()->GetURL(path); 172 GURL url = embedded_test_server()->GetURL(path);
172 ui_test_utils::NavigateToURL(browser(), url); 173 ui_test_utils::NavigateToURL(browser(), url);
173 observer.Wait(); 174 observer.Wait();
174 } 175 }
175 176
176 // Executes |script| and uses the EXPECT macros to check the return value 177 // Waits until the "value" attribute of the HTML element with |element_id| is
177 // against |expected_return_value|. 178 // equal to |expected_value|. If the current value is not as expected, this
178 void CheckScriptReturnValue(std::string& script, bool expected_return_value); 179 // waits until the "change" event is fired for the element. This also
180 // guarantees that once the real value matches the expected, the JavaScript
181 // event loop is spun to allow all other possible events to take place.
182 void WaitForElementValue(const std::string& element_id,
183 const std::string& expected_value);
184 // Checks that the current "value" attribute of the HTML element with
185 // |element_id| is equal to |expected_value|.
186 void CheckElementValue(const std::string& element_id,
187 const std::string& expected_value);
179 188
180 private: 189 private:
181 DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTest); 190 DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTest);
182 }; 191 };
183 192
184 void PasswordManagerBrowserTest::CheckScriptReturnValue( 193 void PasswordManagerBrowserTest::WaitForElementValue(
185 std::string& script, 194 const std::string& element_id,
186 bool expected_return_value) { 195 const std::string& expected_value) {
187 const std::string wrapped_script = 196 enum ReturnCodes { // Possible results of the JavaScript code.
188 std::string("window.domAutomationController.send(") + script + ");"; 197 RETURN_CODE_OK,
189 bool return_value = !expected_return_value; 198 RETURN_CODE_NO_ELEMENT,
199 RETURN_CODE_WRONG_VALUE,
200 RETURN_CODE_INVALID };
bartfab (slow) 2014/06/06 11:19:34 Nit: Put the }; on its own line.
vabr (Chromium) 2014/06/06 17:21:58 Yeah, this one also looked strange to me, but that
201 const std::string value_check_function = base::StringPrintf(
202 "function valueCheck() {"
203 " var element = document.getElementById('%s');"
204 " return element && element.value == '%s';"
205 "}",
206 element_id.c_str(),
207 expected_value.c_str());
208 const std::string script =
209 value_check_function +
210 base::StringPrintf(
211 "if (valueCheck()) {"
212 " /* Spin the event loop with setTimeout. */"
213 " setTimeout(window.domAutomationController.send(%d), 0);"
214 "} else {"
215 " var element = document.getElementById('%s');"
216 " if (!element)"
217 " window.domAutomationController.send(%d);"
218 " element.onchange = function() {"
219 " if (valueCheck()) {"
220 " /* Spin the event loop with setTimeout. */"
221 " setTimeout(window.domAutomationController.send(%d), 0);"
222 " } else {"
223 " window.domAutomationController.send(%d);"
224 " }"
225 " };"
226 "}",
227 RETURN_CODE_OK,
228 element_id.c_str(),
229 RETURN_CODE_NO_ELEMENT,
230 RETURN_CODE_OK,
231 RETURN_CODE_WRONG_VALUE);
232 int return_value = RETURN_CODE_INVALID;
233 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
234 RenderViewHost(), script, &return_value));
235 EXPECT_EQ(RETURN_CODE_OK, return_value)
236 << "element_id = " << element_id
237 << ", expected_value = " << expected_value;
238 }
239
240 void PasswordManagerBrowserTest::CheckElementValue(
241 const std::string& element_id,
242 const std::string& expected_value) {
243 const std::string value_check_script = base::StringPrintf(
244 "var element = document.getElementById('%s');"
245 "window.domAutomationController.send(element && element.value == '%s');",
246 element_id.c_str(),
247 expected_value.c_str());
248 bool return_value = false;
190 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 249 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
191 RenderViewHost(), wrapped_script, &return_value)); 250 RenderViewHost(), value_check_script, &return_value));
192 EXPECT_EQ(expected_return_value, return_value) << "script = " << script; 251 EXPECT_TRUE(return_value) << "element_id = " << element_id
252 << ", expected_value = " << expected_value;
193 } 253 }
194 254
195 // Actual tests --------------------------------------------------------------- 255 // Actual tests ---------------------------------------------------------------
196 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, 256 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
197 PromptForNormalSubmit) { 257 PromptForNormalSubmit) {
198 NavigateToFile("/password/password_form.html"); 258 NavigateToFile("/password/password_form.html");
199 259
200 // Fill a form and submit through a <input type="submit"> button. Nothing 260 // Fill a form and submit through a <input type="submit"> button. Nothing
201 // special. 261 // special.
202 NavigationObserver observer(WebContents()); 262 NavigationObserver observer(WebContents());
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 "document.getElementById('password_field').value = 'random';" 646 "document.getElementById('password_field').value = 'random';"
587 "document.getElementById('input_submit_button').click();" 647 "document.getElementById('input_submit_button').click();"
588 "window.location.href = 'done.html';"; 648 "window.location.href = 'done.html';";
589 649
590 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), save_and_remove)); 650 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), save_and_remove));
591 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame)); 651 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame));
592 observer.Wait(); 652 observer.Wait();
593 // The only thing we check here is that there is no use-after-free reported. 653 // The only thing we check here is that there is no use-after-free reported.
594 } 654 }
595 655
596 // Disabled on Windows due to flakiness: http://crbug.com/346297 656 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, PasswordValueAccessible) {
597 #if defined(OS_WIN)
598 #define MAYBE_PasswordValueAccessible DISABLED_PasswordValueAccessible
599 #else
600 #define MAYBE_PasswordValueAccessible PasswordValueAccessible
601 #endif
602 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
603 MAYBE_PasswordValueAccessible) {
604 NavigateToFile("/password/form_and_link.html"); 657 NavigateToFile("/password/form_and_link.html");
605 658
606 // Click on a link to open a new tab, then switch back to the first one. 659 // Click on a link to open a new tab, then switch back to the first one.
607 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 660 EXPECT_EQ(1, browser()->tab_strip_model()->count());
608 std::string click = 661 std::string click =
609 "document.getElementById('testlink').click();"; 662 "document.getElementById('testlink').click();";
610 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), click)); 663 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), click));
611 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 664 EXPECT_EQ(2, browser()->tab_strip_model()->count());
612 browser()->tab_strip_model()->ActivateTabAt(0, false); 665 browser()->tab_strip_model()->ActivateTabAt(0, false);
613 666
614 // Fill in the credentials, and make sure they are saved. 667 // Fill in the credentials, and make sure they are saved.
615 NavigationObserver form_submit_observer(WebContents()); 668 NavigationObserver form_submit_observer(WebContents());
616 std::string fill_and_submit = 669 std::string fill_and_submit =
617 "document.getElementById('username_field').value = 'temp';" 670 "document.getElementById('username_field').value = 'temp';"
618 "document.getElementById('password_field').value = 'random';" 671 "document.getElementById('password_field').value = 'random';"
619 "document.getElementById('input_submit_button').click();"; 672 "document.getElementById('input_submit_button').click();";
620 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit)); 673 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
621 form_submit_observer.Wait(); 674 form_submit_observer.Wait();
622 EXPECT_TRUE(form_submit_observer.infobar_shown()); 675 EXPECT_TRUE(form_submit_observer.infobar_shown());
623 676
624 // Reload the original page to have the saved credentials autofilled. 677 // Reload the original page to have the saved credentials autofilled.
625 NavigationObserver reload_observer(WebContents()); 678 NavigationObserver reload_observer(WebContents());
626 NavigateToFile("/password/form_and_link.html"); 679 NavigateToFile("/password/form_and_link.html");
627 reload_observer.Wait(); 680 reload_observer.Wait();
628 681
629 // Check that while the username is immediately available, the password value 682 // Wait until the username is filled, to make sure autofill kicked in.
630 // needs a user interaction to show up. 683 WaitForElementValue("username_field", "temp");
631 std::string check_username = 684 // Now check that the password is not accessible yet.
632 "document.getElementById('username_field').value == 'temp'"; 685 CheckElementValue("password_field", "");
633 std::string check_password = 686 // Let the user interact with the page.
634 "document.getElementById('password_field').value == 'random'"; 687 content::SimulateMouseClickAt(
635 CheckScriptReturnValue(check_username, true); 688 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1,1));
636 CheckScriptReturnValue(check_password, false); 689 // Wait until that interaction causes the password value to be revealed.
637 content::SimulateMouseClick( 690 WaitForElementValue("password_field", "random");
638 WebContents(), 0, blink::WebMouseEvent::ButtonLeft); 691 // And check that after the side-effects of the interaction took place, the
639 CheckScriptReturnValue(check_username, true); 692 // username value stays the same.
640 CheckScriptReturnValue(check_password, true); 693 CheckElementValue("username_field", "temp");
641 } 694 }
642 695
643 // The following test is limited to Aura, because 696 // The following test is limited to Aura, because
644 // RenderWidgetHostViewGuest::ProcessAckedTouchEvent is, and 697 // RenderWidgetHostViewGuest::ProcessAckedTouchEvent is, and
645 // ProcessAckedTouchEvent is what triggers the translation of touch events to 698 // ProcessAckedTouchEvent is what triggers the translation of touch events to
646 // gesture events. 699 // gesture events.
647 #if defined(USE_AURA) 700 #if defined(USE_AURA)
648 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, 701 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
649 PasswordValueAccessibleOnSubmit) { 702 PasswordValueAccessibleOnSubmit) {
650 NavigateToFile("/password/form_and_link.html"); 703 NavigateToFile("/password/form_and_link.html");
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill)); 800 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill));
748 801
749 NavigationObserver observer(WebContents()); 802 NavigationObserver observer(WebContents());
750 GURL url = embedded_test_server()->GetURL("/password/password_form.html"); 803 GURL url = embedded_test_server()->GetURL("/password/password_form.html");
751 chrome::NavigateParams params(browser(), url, 804 chrome::NavigateParams params(browser(), url,
752 content::PAGE_TRANSITION_RELOAD); 805 content::PAGE_TRANSITION_RELOAD);
753 ui_test_utils::NavigateToURL(&params); 806 ui_test_utils::NavigateToURL(&params);
754 observer.Wait(); 807 observer.Wait();
755 EXPECT_FALSE(observer.infobar_shown()); 808 EXPECT_FALSE(observer.infobar_shown());
756 } 809 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698