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/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 Loading... | |
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 Loading... | |
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 Loading... | |
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(¶ms); | 806 ui_test_utils::NavigateToURL(¶ms); |
754 observer.Wait(); | 807 observer.Wait(); |
755 EXPECT_FALSE(observer.infobar_shown()); | 808 EXPECT_FALSE(observer.infobar_shown()); |
756 } | 809 } |
OLD | NEW |