1 // Copyright 2014 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/command_line.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
8 #include "chrome/browser/password_manager/password_manager_test_base.h"
9 #include "chrome/browser/password_manager/password_store_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/autofill/password_generation_popup_observer.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "components/autofill/core/browser/autofill_test_utils.h"
17 #include "components/autofill/core/common/autofill_switches.h"
18 #include "components/password_manager/core/browser/password_generation_manager.h"
19 #include "components/password_manager/core/browser/test_password_store.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/events/keycodes/keyboard_codes.h"
29 class TestPopupObserver
: public autofill::PasswordGenerationPopupObserver
{
32 : popup_showing_(false),
33 password_visible_(false) {}
34 virtual ~TestPopupObserver() {}
36 void OnPopupShown(bool password_visible
) override
{
37 popup_showing_
= true;
38 password_visible_
= password_visible
;
41 void OnPopupHidden() override
{ popup_showing_
= false; }
43 bool popup_showing() { return popup_showing_
; }
44 bool password_visible() { return password_visible_
; }
48 bool password_visible_
;
53 class PasswordGenerationInteractiveTest
:
54 public PasswordManagerBrowserTestBase
{
56 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
57 // Make sure the feature is enabled.
58 command_line
->AppendSwitch(autofill::switches::kEnablePasswordGeneration
);
60 // Don't require ping from autofill or blacklist checking.
61 command_line
->AppendSwitch(
62 autofill::switches::kLocalHeuristicsOnlyForPasswordGeneration
);
65 void SetUpOnMainThread() override
{
66 PasswordManagerBrowserTestBase::SetUpOnMainThread();
68 // Disable Autofill requesting access to AddressBook data. This will cause
69 // the tests to hang on Mac.
70 autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
72 // Set observer for popup.
73 ChromePasswordManagerClient
* client
=
74 ChromePasswordManagerClient::FromWebContents(WebContents());
75 client
->SetTestObserver(&observer_
);
77 NavigateToFile("/password/signup_form.html");
80 void TearDownOnMainThread() override
{
81 PasswordManagerBrowserTestBase::TearDownOnMainThread();
84 ChromePasswordManagerClient
* client
=
85 ChromePasswordManagerClient::FromWebContents(WebContents());
86 client
->HidePasswordGenerationPopup();
89 std::string
GetFieldValue(const std::string
& field_id
) {
91 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
93 "window.domAutomationController.send("
94 " document.getElementById('" + field_id
+ "').value);",
99 std::string
GetFocusedElement() {
100 std::string focused_element
;
101 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
103 "window.domAutomationController.send("
104 " document.activeElement.id)",
106 return focused_element
;
109 void FocusPasswordField() {
110 ASSERT_TRUE(content::ExecuteScript(
112 "document.getElementById('password_field').focus()"));
115 void SendKeyToPopup(ui::KeyboardCode key
) {
116 content::NativeWebKeyboardEvent event
;
117 event
.windowsKeyCode
= key
;
118 event
.type
= blink::WebKeyboardEvent::RawKeyDown
;
119 RenderViewHost()->ForwardKeyboardEvent(event
);
122 bool GenerationPopupShowing() {
123 return observer_
.popup_showing() && observer_
.password_visible();
126 bool EditingPopupShowing() {
127 return observer_
.popup_showing() && !observer_
.password_visible();
131 TestPopupObserver observer_
;
134 // Disabled due to flakiness due to resizes, see http://crbug.com/407998.
135 IN_PROC_BROWSER_TEST_F(PasswordGenerationInteractiveTest
,
136 DISABLED_PopupShownAndPasswordSelected
) {
137 FocusPasswordField();
138 EXPECT_TRUE(GenerationPopupShowing());
139 SendKeyToPopup(ui::VKEY_DOWN
);
140 SendKeyToPopup(ui::VKEY_RETURN
);
142 // Selecting the password should fill the field and move focus to the
144 EXPECT_FALSE(GetFieldValue("password_field").empty());
145 EXPECT_FALSE(GenerationPopupShowing());
146 EXPECT_FALSE(EditingPopupShowing());
147 EXPECT_EQ("input_submit_button", GetFocusedElement());
149 // Re-focusing the password field should show the editing popup.
150 FocusPasswordField();
151 EXPECT_TRUE(EditingPopupShowing());
154 // Disabled due to flakiness due to resizes, see http://crbug.com/407998.
155 IN_PROC_BROWSER_TEST_F(PasswordGenerationInteractiveTest
,
156 DISABLED_PopupShownAndDismissed
) {
157 FocusPasswordField();
158 EXPECT_TRUE(GenerationPopupShowing());
160 SendKeyToPopup(ui::VKEY_ESCAPE
);
162 // Popup is dismissed.
163 EXPECT_FALSE(GenerationPopupShowing());
166 // Disabled due to flakiness due to resizes, see http://crbug.com/407998.
167 IN_PROC_BROWSER_TEST_F(PasswordGenerationInteractiveTest
,
168 DISABLED_PopupShownAndDismissedByScrolling
) {
169 FocusPasswordField();
170 EXPECT_TRUE(GenerationPopupShowing());
172 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
173 "window.scrollTo(100, 0);"));
175 EXPECT_FALSE(GenerationPopupShowing());
178 // Disabled due to flakiness due to resizes, see http://crbug.com/407998.
179 IN_PROC_BROWSER_TEST_F(PasswordGenerationInteractiveTest
,
180 DISABLED_GenerationTriggeredInIFrame
) {
181 NavigateToFile("/password/framed_signup_form.html");
183 std::string focus_script
=
184 "var frame = document.getElementById('signup_iframe');"
185 "var frame_doc = frame.contentDocument;"
186 "frame_doc.getElementById('password_field').focus();";
188 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), focus_script
));
189 EXPECT_TRUE(GenerationPopupShowing());
192 // Disabled due to flakiness due to resizes, see http://crbug.com/407998.
193 IN_PROC_BROWSER_TEST_F(PasswordGenerationInteractiveTest
,
194 DISABLED_AutoSavingGeneratedPassword
) {
195 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
196 static_cast<password_manager::TestPasswordStore
*>(
197 PasswordStoreFactory::GetForProfile(
198 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
200 FocusPasswordField();
201 EXPECT_TRUE(GenerationPopupShowing());
202 SendKeyToPopup(ui::VKEY_DOWN
);
203 SendKeyToPopup(ui::VKEY_RETURN
);
205 // Change username and submit.
206 NavigationObserver
observer(WebContents());
207 std::string submit_script
=
208 "document.getElementById('username_field').value = 'something';"
209 "document.getElementById('input_submit_button').click()";
210 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit_script
));
213 // Spin the message loop to make sure the password store had a chance to save
215 base::RunLoop run_loop
;
216 run_loop
.RunUntilIdle();
217 EXPECT_FALSE(password_store
->IsEmpty());
219 // Make sure the username is correct.
220 password_manager::TestPasswordStore::PasswordMap stored_passwords
=
221 password_store
->stored_passwords();
222 EXPECT_EQ(1u, stored_passwords
.size());
223 EXPECT_EQ(1u, stored_passwords
.begin()->second
.size());
224 EXPECT_EQ(base::UTF8ToUTF16("something"),
225 (stored_passwords
.begin()->second
)[0].username_value
);