1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/run_loop.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/password_manager/password_manager_test_base.h"
8 #include "chrome/browser/password_manager/password_store_factory.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "components/password_manager/core/browser/test_password_store.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/test_utils.h"
13 #include "ui/events/keycodes/keyboard_codes.h"
17 void SimulateUserTypingInField(content::RenderViewHost
* render_view_host
,
18 content::WebContents
* web_contents
,
19 const std::string
& field_id
) {
20 std::string
focus("document.getElementById('" + field_id
+ "').focus();");
21 ASSERT_TRUE(content::ExecuteScript(render_view_host
, focus
));
23 content::SimulateKeyPress(web_contents
, ui::VKEY_O
, false, false, false,
25 content::SimulateKeyPress(web_contents
, ui::VKEY_R
, false, false, false,
27 content::SimulateKeyPress(web_contents
, ui::VKEY_A
, false, false, false,
29 content::SimulateKeyPress(web_contents
, ui::VKEY_R
, false, false, false,
31 content::SimulateKeyPress(web_contents
, ui::VKEY_Y
, false, false, false,
37 namespace password_manager
{
39 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, UsernameChanged
) {
40 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
41 static_cast<password_manager::TestPasswordStore
*>(
42 PasswordStoreFactory::GetForProfile(
43 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
45 NavigateToFile("/password/signup_form.html");
47 NavigationObserver
observer(WebContents());
48 scoped_ptr
<PromptObserver
> prompt_observer(
49 PromptObserver::Create(WebContents()));
50 std::string fill_and_submit
=
51 "document.getElementById('username_field').value = 'temp';"
52 "document.getElementById('password_field').value = 'random';"
53 "document.getElementById('input_submit_button').click()";
54 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
56 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
57 prompt_observer
->Accept();
59 // Spin the message loop to make sure the password store had a chance to save
61 base::RunLoop run_loop
;
62 run_loop
.RunUntilIdle();
63 EXPECT_FALSE(password_store
->IsEmpty());
65 // Reload the original page to have the saved credentials autofilled.
66 NavigationObserver
reload_observer(WebContents());
67 NavigateToFile("/password/signup_form.html");
68 reload_observer
.Wait();
70 // Let the user interact with the page, so that DOM gets modification events,
71 // needed for autofilling fields.
72 content::SimulateMouseClickAt(
73 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(1, 1));
75 WaitForElementValue("username_field", "temp");
76 WaitForElementValue("password_field", "random");
78 // Change username and submit. This should add the characters "ORARY" to the
79 // already autofilled username.
80 SimulateUserTypingInField(RenderViewHost(), WebContents(), "username_field");
81 // TODO(gcasto): Not sure why this click is required.
82 content::SimulateMouseClickAt(
83 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(1, 1));
84 WaitForElementValue("username_field", "tempORARY");
86 NavigationObserver
second_observer(WebContents());
87 scoped_ptr
<PromptObserver
> second_prompt_observer(
88 PromptObserver::Create(WebContents()));
90 "document.getElementById('input_submit_button').click();";
91 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
92 second_observer
.Wait();
93 EXPECT_TRUE(second_prompt_observer
->IsShowingPrompt());
94 second_prompt_observer
->Accept();
96 // Spin the message loop to make sure the password store had a chance to save
98 base::RunLoop third_run_loop
;
99 third_run_loop
.RunUntilIdle();
100 EXPECT_FALSE(password_store
->IsEmpty());
102 // Verify that there are two saved password, the old password and the new
104 password_manager::TestPasswordStore::PasswordMap stored_passwords
=
105 password_store
->stored_passwords();
106 EXPECT_EQ(1u, stored_passwords
.size());
107 EXPECT_EQ(2u, stored_passwords
.begin()->second
.size());
108 EXPECT_EQ(base::UTF8ToUTF16("temp"),
109 (stored_passwords
.begin()->second
)[0].username_value
);
110 EXPECT_EQ(base::UTF8ToUTF16("tempORARY"),
111 (stored_passwords
.begin()->second
)[1].username_value
);
114 } // namespace password_manager