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
3 // found in the LICENSE file.
7 #include "base/command_line.h"
8 #include "base/metrics/histogram_samples.h"
9 #include "base/metrics/statistics_recorder.h"
10 #include "base/path_service.h"
11 #include "base/run_loop.h"
12 #include "base/stl_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
17 #include "chrome/browser/password_manager/password_manager_test_base.h"
18 #include "chrome/browser/password_manager/password_store_factory.h"
19 #include "chrome/browser/password_manager/test_password_store_service.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/login/login_prompt.h"
23 #include "chrome/browser/ui/login/login_prompt_test_utils.h"
24 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
26 #include "chrome/common/channel_info.h"
27 #include "chrome/common/chrome_paths.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/test/base/test_switches.h"
30 #include "chrome/test/base/ui_test_utils.h"
31 #include "components/autofill/content/common/autofill_messages.h"
32 #include "components/autofill/core/browser/autofill_test_utils.h"
33 #include "components/autofill/core/browser/test_autofill_client.h"
34 #include "components/autofill/core/common/password_form.h"
35 #include "components/password_manager/content/browser/content_password_manager_driver.h"
36 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
37 #include "components/password_manager/core/browser/test_password_store.h"
38 #include "components/password_manager/core/common/password_manager_switches.h"
39 #include "components/version_info/version_info.h"
40 #include "content/public/browser/navigation_controller.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/render_frame_host.h"
43 #include "content/public/browser/render_process_host.h"
44 #include "content/public/browser/render_view_host.h"
45 #include "content/public/browser/web_contents.h"
46 #include "content/public/browser/web_contents_observer.h"
47 #include "content/public/common/content_switches.h"
48 #include "content/public/test/browser_test_utils.h"
49 #include "content/public/test/test_utils.h"
50 #include "ipc/ipc_security_test_util.h"
51 #include "net/base/filename_util.h"
52 #include "net/dns/mock_host_resolver.h"
53 #include "net/test/embedded_test_server/embedded_test_server.h"
54 #include "net/test/embedded_test_server/http_request.h"
55 #include "net/test/embedded_test_server/http_response.h"
56 #include "net/test/spawned_test_server/spawned_test_server.h"
57 #include "net/url_request/test_url_fetcher_factory.h"
58 #include "testing/gmock/include/gmock/gmock.h"
59 #include "third_party/WebKit/public/web/WebInputEvent.h"
60 #include "ui/events/keycodes/keyboard_codes.h"
61 #include "ui/gfx/geometry/point.h"
65 GURL
GetFileURL(const char* filename
) {
67 PathService::Get(chrome::DIR_TEST_DATA
, &path
);
68 path
= path
.AppendASCII("password").AppendASCII(filename
);
69 CHECK(base::PathExists(path
));
70 return net::FilePathToFileURL(path
);
73 // Handles |request| to "/basic_auth". If "Authorization" header is present,
74 // responds with a non-empty HTTP 200 page (regardless of its value). Otherwise
75 // serves a Basic Auth challenge.
76 scoped_ptr
<net::test_server::HttpResponse
> HandleTestAuthRequest(
77 const net::test_server::HttpRequest
& request
) {
78 if (!base::StartsWith(request
.relative_url
, "/basic_auth",
79 base::CompareCase::SENSITIVE
))
80 return scoped_ptr
<net::test_server::HttpResponse
>();
82 if (ContainsKey(request
.headers
, "Authorization")) {
83 scoped_ptr
<net::test_server::BasicHttpResponse
> http_response(
84 new net::test_server::BasicHttpResponse
);
85 http_response
->set_code(net::HTTP_OK
);
86 http_response
->set_content("Success!");
87 return http_response
.Pass();
89 scoped_ptr
<net::test_server::BasicHttpResponse
> http_response(
90 new net::test_server::BasicHttpResponse
);
91 http_response
->set_code(net::HTTP_UNAUTHORIZED
);
92 http_response
->AddCustomHeader("WWW-Authenticate",
93 "Basic realm=\"test realm\"");
94 return http_response
.Pass();
98 class ObservingAutofillClient
: public autofill::TestAutofillClient
{
100 ObservingAutofillClient()
101 : message_loop_runner_(new content::MessageLoopRunner
) {}
102 ~ObservingAutofillClient() override
{}
104 void Wait() { message_loop_runner_
->Run(); }
106 void ShowAutofillPopup(
107 const gfx::RectF
& element_bounds
,
108 base::i18n::TextDirection text_direction
,
109 const std::vector
<autofill::Suggestion
>& suggestions
,
110 base::WeakPtr
<autofill::AutofillPopupDelegate
> delegate
) override
{
111 message_loop_runner_
->Quit();
115 scoped_refptr
<content::MessageLoopRunner
> message_loop_runner_
;
117 DISALLOW_COPY_AND_ASSIGN(ObservingAutofillClient
);
120 // For simplicity we assume that password store contains only 1 credentials.
121 void CheckThatCredentialsStored(
122 password_manager::TestPasswordStore
* password_store
,
123 const base::string16
& username
,
124 const base::string16
& password
) {
125 auto& passwords_map
= password_store
->stored_passwords();
126 ASSERT_EQ(1u, passwords_map
.size());
127 auto& passwords_vector
= passwords_map
.begin()->second
;
128 ASSERT_EQ(1u, passwords_vector
.size());
129 const autofill::PasswordForm
& form
= passwords_vector
[0];
130 EXPECT_EQ(username
, form
.username_value
);
131 EXPECT_EQ(password
, form
.password_value
);
136 namespace password_manager
{
138 // Actual tests ---------------------------------------------------------------
139 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, PromptForNormalSubmit
) {
140 NavigateToFile("/password/password_form.html");
142 // Fill a form and submit through a <input type="submit"> button. Nothing
144 NavigationObserver
observer(WebContents());
145 scoped_ptr
<PromptObserver
> prompt_observer(
146 PromptObserver::Create(WebContents()));
147 std::string fill_and_submit
=
148 "document.getElementById('username_field').value = 'temp';"
149 "document.getElementById('password_field').value = 'random';"
150 "document.getElementById('input_submit_button').click()";
151 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
153 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
156 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
157 PromptForSubmitWithInPageNavigation
) {
158 NavigateToFile("/password/password_navigate_before_submit.html");
160 // Fill a form and submit through a <input type="submit"> button. Nothing
161 // special. The form does an in-page navigation before submitting.
162 NavigationObserver
observer(WebContents());
163 scoped_ptr
<PromptObserver
> prompt_observer(
164 PromptObserver::Create(WebContents()));
165 std::string fill_and_submit
=
166 "document.getElementById('username_field').value = 'temp';"
167 "document.getElementById('password_field').value = 'random';"
168 "document.getElementById('input_submit_button').click()";
169 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
171 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
174 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
175 LoginSuccessWithUnrelatedForm
) {
176 // Log in, see a form on the landing page. That form is not related to the
177 // login form (=has a different action), so we should offer saving the
179 NavigateToFile("/password/password_form.html");
181 NavigationObserver
observer(WebContents());
182 scoped_ptr
<PromptObserver
> prompt_observer(
183 PromptObserver::Create(WebContents()));
184 std::string fill_and_submit
=
185 "document.getElementById('username_unrelated').value = 'temp';"
186 "document.getElementById('password_unrelated').value = 'random';"
187 "document.getElementById('submit_unrelated').click()";
188 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
190 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
193 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, LoginFailed
) {
194 // Log in, see a form on the landing page. That form is not related to the
195 // login form (=has a different action), so we should offer saving the
197 NavigateToFile("/password/password_form.html");
199 NavigationObserver
observer(WebContents());
200 scoped_ptr
<PromptObserver
> prompt_observer(
201 PromptObserver::Create(WebContents()));
202 std::string fill_and_submit
=
203 "document.getElementById('username_failed').value = 'temp';"
204 "document.getElementById('password_failed').value = 'random';"
205 "document.getElementById('submit_failed').click()";
206 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
208 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
211 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, Redirects
) {
212 NavigateToFile("/password/password_form.html");
214 // Fill a form and submit through a <input type="submit"> button. The form
215 // points to a redirection page.
216 NavigationObserver
observer(WebContents());
217 scoped_ptr
<PromptObserver
> prompt_observer(
218 PromptObserver::Create(WebContents()));
219 std::string fill_and_submit
=
220 "document.getElementById('username_redirect').value = 'temp';"
221 "document.getElementById('password_redirect').value = 'random';"
222 "document.getElementById('submit_redirect').click()";
223 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
225 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
227 // The redirection page now redirects via Javascript. We check that the
229 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
230 "window.location.href = 'done.html';"));
232 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
235 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
236 PromptForSubmitUsingJavaScript
) {
237 NavigateToFile("/password/password_form.html");
239 // Fill a form and submit using <button> that calls submit() on the form.
240 // This should work regardless of the type of element, as long as submit() is
242 NavigationObserver
observer(WebContents());
243 scoped_ptr
<PromptObserver
> prompt_observer(
244 PromptObserver::Create(WebContents()));
245 std::string fill_and_submit
=
246 "document.getElementById('username_field').value = 'temp';"
247 "document.getElementById('password_field').value = 'random';"
248 "document.getElementById('submit_button').click()";
249 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
251 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
254 // Flaky: crbug.com/301547, observed on win and mac. Probably happens on all
256 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
257 DISABLED_PromptForDynamicForm
) {
258 NavigateToFile("/password/dynamic_password_form.html");
260 // Fill the dynamic password form and submit.
261 NavigationObserver
observer(WebContents());
262 scoped_ptr
<PromptObserver
> prompt_observer(
263 PromptObserver::Create(WebContents()));
264 std::string fill_and_submit
=
265 "document.getElementById('create_form_button').click();"
266 "window.setTimeout(function() {"
267 " document.dynamic_form.username.value = 'tempro';"
268 " document.dynamic_form.password.value = 'random';"
269 " document.dynamic_form.submit();"
271 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
273 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
276 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, NoPromptForNavigation
) {
277 NavigateToFile("/password/password_form.html");
279 // Don't fill the password form, just navigate away. Shouldn't prompt.
280 NavigationObserver
observer(WebContents());
281 scoped_ptr
<PromptObserver
> prompt_observer(
282 PromptObserver::Create(WebContents()));
283 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
284 "window.location.href = 'done.html';"));
286 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
289 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
290 NoPromptForSubFrameNavigation
) {
291 NavigateToFile("/password/multi_frames.html");
293 // If you are filling out a password form in one frame and a different frame
294 // navigates, this should not trigger the infobar.
295 NavigationObserver
observer(WebContents());
296 scoped_ptr
<PromptObserver
> prompt_observer(
297 PromptObserver::Create(WebContents()));
298 observer
.SetPathToWaitFor("/password/done.html");
300 "var first_frame = document.getElementById('first_frame');"
301 "var frame_doc = first_frame.contentDocument;"
302 "frame_doc.getElementById('username_field').value = 'temp';"
303 "frame_doc.getElementById('password_field').value = 'random';";
304 std::string navigate_frame
=
305 "var second_iframe = document.getElementById('second_frame');"
306 "second_iframe.contentWindow.location.href = 'done.html';";
308 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill
));
309 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame
));
311 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
314 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
315 PromptAfterSubmitWithSubFrameNavigation
) {
316 NavigateToFile("/password/multi_frames.html");
318 // Make sure that we prompt to save password even if a sub-frame navigation
320 NavigationObserver
observer(WebContents());
321 scoped_ptr
<PromptObserver
> prompt_observer(
322 PromptObserver::Create(WebContents()));
323 observer
.SetPathToWaitFor("/password/done.html");
324 std::string navigate_frame
=
325 "var second_iframe = document.getElementById('second_frame');"
326 "second_iframe.contentWindow.location.href = 'other.html';";
327 std::string fill_and_submit
=
328 "var first_frame = document.getElementById('first_frame');"
329 "var frame_doc = first_frame.contentDocument;"
330 "frame_doc.getElementById('username_field').value = 'temp';"
331 "frame_doc.getElementById('password_field').value = 'random';"
332 "frame_doc.getElementById('input_submit_button').click();";
334 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame
));
335 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
337 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
340 IN_PROC_BROWSER_TEST_F(
341 PasswordManagerBrowserTestBase
,
342 NoPromptForFailedLoginFromMainFrameWithMultiFramesInPage
) {
343 NavigateToFile("/password/multi_frames.html");
345 // Make sure that we don't prompt to save the password for a failed login
346 // from the main frame with multiple frames in the same page.
347 NavigationObserver
observer(WebContents());
348 scoped_ptr
<PromptObserver
> prompt_observer(
349 PromptObserver::Create(WebContents()));
350 std::string fill_and_submit
=
351 "document.getElementById('username_failed').value = 'temp';"
352 "document.getElementById('password_failed').value = 'random';"
353 "document.getElementById('submit_failed').click();";
355 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
357 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
360 // Disabled on Mac due to flakiness: crbug.com/493263
361 #if defined(OS_MACOSX)
362 #define MAYBE_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage \
363 DISABLED_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage
365 #define MAYBE_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage \
366 NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage
368 IN_PROC_BROWSER_TEST_F(
369 PasswordManagerBrowserTestBase
,
370 MAYBE_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage
) {
371 NavigateToFile("/password/multi_frames.html");
373 // Make sure that we don't prompt to save the password for a failed login
374 // from a sub-frame with multiple frames in the same page.
375 NavigationObserver
observer(WebContents());
376 scoped_ptr
<PromptObserver
> prompt_observer(
377 PromptObserver::Create(WebContents()));
378 std::string fill_and_submit
=
379 "var first_frame = document.getElementById('first_frame');"
380 "var frame_doc = first_frame.contentDocument;"
381 "frame_doc.getElementById('username_failed').value = 'temp';"
382 "frame_doc.getElementById('password_failed').value = 'random';"
383 "frame_doc.getElementById('submit_failed').click();";
385 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
386 observer
.SetPathToWaitFor("/password/failed.html");
388 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
391 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, PromptForXHRSubmit
) {
392 #if defined(OS_WIN) && defined(USE_ASH)
393 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
394 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
395 ::switches::kAshBrowserTests
))
398 NavigateToFile("/password/password_xhr_submit.html");
400 // Verify that we show the save password prompt if a form returns false
401 // in its onsubmit handler but instead logs in/navigates via XHR.
402 // Note that calling 'submit()' on a form with javascript doesn't call
403 // the onsubmit handler, so we click the submit button instead.
404 NavigationObserver
observer(WebContents());
405 scoped_ptr
<PromptObserver
> prompt_observer(
406 PromptObserver::Create(WebContents()));
407 std::string fill_and_submit
=
408 "document.getElementById('username_field').value = 'temp';"
409 "document.getElementById('password_field').value = 'random';"
410 "document.getElementById('submit_button').click()";
411 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
413 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
416 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
417 PromptForXHRWithoutOnSubmit
) {
418 NavigateToFile("/password/password_xhr_submit.html");
420 // Verify that if XHR navigation occurs and the form is properly filled out,
421 // we try and save the password even though onsubmit hasn't been called.
422 NavigationObserver
observer(WebContents());
423 scoped_ptr
<PromptObserver
> prompt_observer(
424 PromptObserver::Create(WebContents()));
425 std::string fill_and_navigate
=
426 "document.getElementById('username_field').value = 'temp';"
427 "document.getElementById('password_field').value = 'random';"
429 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate
));
431 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
434 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
435 PromptForXHRWithNewPasswordsWithoutOnSubmit
) {
436 NavigateToFile("/password/password_xhr_submit.html");
438 // Verify that if XHR navigation occurs and the form is properly filled out,
439 // we try and save the password even though onsubmit hasn't been called.
440 // Specifically verify that the password form saving new passwords is treated
441 // the same as a login form.
442 NavigationObserver
observer(WebContents());
443 scoped_ptr
<PromptObserver
> prompt_observer(
444 PromptObserver::Create(WebContents()));
445 std::string fill_and_navigate
=
446 "document.getElementById('signup_username_field').value = 'temp';"
447 "document.getElementById('signup_password_field').value = 'random';"
448 "document.getElementById('confirmation_password_field').value = 'random';"
450 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate
));
452 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
455 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
456 PromptForXHRSubmitWithoutNavigation
) {
457 NavigateToFile("/password/password_xhr_submit.html");
459 // Need to pay attention for a message that XHR has finished since there
460 // is no navigation to wait for.
461 content::DOMMessageQueue message_queue
;
463 // Verify that if XHR without navigation occurs and the form has been filled
464 // out we try and save the password. Note that in general the submission
465 // doesn't need to be via form.submit(), but for testing purposes it's
466 // necessary since we otherwise ignore changes made to the value of these
468 scoped_ptr
<PromptObserver
> prompt_observer(
469 PromptObserver::Create(WebContents()));
470 std::string fill_and_submit
=
472 "document.getElementById('username_field').value = 'temp';"
473 "document.getElementById('password_field').value = 'random';"
474 "document.getElementById('submit_button').click();";
475 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
477 while (message_queue
.WaitForMessage(&message
)) {
478 if (message
== "\"XHR_FINISHED\"")
482 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
485 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
486 PromptForXHRSubmitWithoutNavigation_SignupForm
) {
487 NavigateToFile("/password/password_xhr_submit.html");
489 // Need to pay attention for a message that XHR has finished since there
490 // is no navigation to wait for.
491 content::DOMMessageQueue message_queue
;
493 // Verify that if XHR without navigation occurs and the form has been filled
494 // out we try and save the password. Note that in general the submission
495 // doesn't need to be via form.submit(), but for testing purposes it's
496 // necessary since we otherwise ignore changes made to the value of these
498 scoped_ptr
<PromptObserver
> prompt_observer(
499 PromptObserver::Create(WebContents()));
500 std::string fill_and_submit
=
502 "document.getElementById('signup_username_field').value = 'temp';"
503 "document.getElementById('signup_password_field').value = 'random';"
504 "document.getElementById('confirmation_password_field').value = 'random';"
505 "document.getElementById('signup_submit_button').click();";
506 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
508 while (message_queue
.WaitForMessage(&message
)) {
509 if (message
== "\"XHR_FINISHED\"")
513 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
516 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
517 NoPromptForXHRSubmitWithoutNavigationWithUnfilledForm
) {
518 NavigateToFile("/password/password_xhr_submit.html");
520 // Need to pay attention for a message that XHR has finished since there
521 // is no navigation to wait for.
522 content::DOMMessageQueue message_queue
;
524 // Verify that if XHR without navigation occurs and the form has NOT been
525 // filled out we don't prompt.
526 scoped_ptr
<PromptObserver
> prompt_observer(
527 PromptObserver::Create(WebContents()));
528 std::string fill_and_submit
=
530 "document.getElementById('username_field').value = 'temp';"
531 "document.getElementById('submit_button').click();";
532 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
534 while (message_queue
.WaitForMessage(&message
)) {
535 if (message
== "\"XHR_FINISHED\"")
539 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
542 IN_PROC_BROWSER_TEST_F(
543 PasswordManagerBrowserTestBase
,
544 NoPromptForXHRSubmitWithoutNavigationWithUnfilledForm_SignupForm
) {
545 NavigateToFile("/password/password_xhr_submit.html");
547 // Need to pay attention for a message that XHR has finished since there
548 // is no navigation to wait for.
549 content::DOMMessageQueue message_queue
;
551 // Verify that if XHR without navigation occurs and the form has NOT been
552 // filled out we don't prompt.
553 scoped_ptr
<PromptObserver
> prompt_observer(
554 PromptObserver::Create(WebContents()));
555 std::string fill_and_submit
=
557 "document.getElementById('signup_username_field').value = 'temp';"
558 "document.getElementById('signup_submit_button').click();";
559 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
561 while (message_queue
.WaitForMessage(&message
)) {
562 if (message
== "\"XHR_FINISHED\"")
566 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
569 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, PromptForFetchSubmit
) {
570 #if defined(OS_WIN) && defined(USE_ASH)
571 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
572 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
573 ::switches::kAshBrowserTests
))
576 NavigateToFile("/password/password_fetch_submit.html");
578 // Verify that we show the save password prompt if a form returns false
579 // in its onsubmit handler but instead logs in/navigates via Fetch.
580 // Note that calling 'submit()' on a form with javascript doesn't call
581 // the onsubmit handler, so we click the submit button instead.
582 NavigationObserver
observer(WebContents());
583 scoped_ptr
<PromptObserver
> prompt_observer(
584 PromptObserver::Create(WebContents()));
585 std::string fill_and_submit
=
586 "document.getElementById('username_field').value = 'temp';"
587 "document.getElementById('password_field').value = 'random';"
588 "document.getElementById('submit_button').click()";
589 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
591 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
594 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
595 PromptForFetchWithoutOnSubmit
) {
596 NavigateToFile("/password/password_fetch_submit.html");
598 // Verify that if Fetch navigation occurs and the form is properly filled out,
599 // we try and save the password even though onsubmit hasn't been called.
600 NavigationObserver
observer(WebContents());
601 scoped_ptr
<PromptObserver
> prompt_observer(
602 PromptObserver::Create(WebContents()));
603 std::string fill_and_navigate
=
604 "document.getElementById('username_field').value = 'temp';"
605 "document.getElementById('password_field').value = 'random';"
607 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate
));
609 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
612 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
613 PromptForFetchWithNewPasswordsWithoutOnSubmit
) {
614 NavigateToFile("/password/password_fetch_submit.html");
616 // Verify that if Fetch navigation occurs and the form is properly filled out,
617 // we try and save the password even though onsubmit hasn't been called.
618 // Specifically verify that the password form saving new passwords is treated
619 // the same as a login form.
620 NavigationObserver
observer(WebContents());
621 scoped_ptr
<PromptObserver
> prompt_observer(
622 PromptObserver::Create(WebContents()));
623 std::string fill_and_navigate
=
624 "document.getElementById('signup_username_field').value = 'temp';"
625 "document.getElementById('signup_password_field').value = 'random';"
626 "document.getElementById('confirmation_password_field').value = 'random';"
628 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate
));
630 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
633 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
634 PromptForFetchSubmitWithoutNavigation
) {
635 NavigateToFile("/password/password_fetch_submit.html");
637 // Need to pay attention for a message that XHR has finished since there
638 // is no navigation to wait for.
639 content::DOMMessageQueue message_queue
;
641 // Verify that if XHR without navigation occurs and the form has been filled
642 // out we try and save the password. Note that in general the submission
643 // doesn't need to be via form.submit(), but for testing purposes it's
644 // necessary since we otherwise ignore changes made to the value of these
646 scoped_ptr
<PromptObserver
> prompt_observer(
647 PromptObserver::Create(WebContents()));
648 std::string fill_and_submit
=
650 "document.getElementById('username_field').value = 'temp';"
651 "document.getElementById('password_field').value = 'random';"
652 "document.getElementById('submit_button').click();";
653 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
655 while (message_queue
.WaitForMessage(&message
)) {
656 if (message
== "\"FETCH_FINISHED\"")
660 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
663 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
664 PromptForFetchSubmitWithoutNavigation_SignupForm
) {
665 NavigateToFile("/password/password_fetch_submit.html");
667 // Need to pay attention for a message that Fetch has finished since there
668 // is no navigation to wait for.
669 content::DOMMessageQueue message_queue
;
671 // Verify that if Fetch without navigation occurs and the form has been filled
672 // out we try and save the password. Note that in general the submission
673 // doesn't need to be via form.submit(), but for testing purposes it's
674 // necessary since we otherwise ignore changes made to the value of these
676 scoped_ptr
<PromptObserver
> prompt_observer(
677 PromptObserver::Create(WebContents()));
678 std::string fill_and_submit
=
680 "document.getElementById('signup_username_field').value = 'temp';"
681 "document.getElementById('signup_password_field').value = 'random';"
682 "document.getElementById('confirmation_password_field').value = 'random';"
683 "document.getElementById('signup_submit_button').click();";
684 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
686 while (message_queue
.WaitForMessage(&message
)) {
687 if (message
== "\"FETCH_FINISHED\"")
691 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
694 IN_PROC_BROWSER_TEST_F(
695 PasswordManagerBrowserTestBase
,
696 NoPromptForFetchSubmitWithoutNavigationWithUnfilledForm
) {
697 NavigateToFile("/password/password_fetch_submit.html");
699 // Need to pay attention for a message that Fetch has finished since there
700 // is no navigation to wait for.
701 content::DOMMessageQueue message_queue
;
703 // Verify that if Fetch without navigation occurs and the form has NOT been
704 // filled out we don't prompt.
705 scoped_ptr
<PromptObserver
> prompt_observer(
706 PromptObserver::Create(WebContents()));
707 std::string fill_and_submit
=
709 "document.getElementById('username_field').value = 'temp';"
710 "document.getElementById('submit_button').click();";
711 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
713 while (message_queue
.WaitForMessage(&message
)) {
714 if (message
== "\"FETCH_FINISHED\"")
718 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
721 IN_PROC_BROWSER_TEST_F(
722 PasswordManagerBrowserTestBase
,
723 NoPromptForFetchSubmitWithoutNavigationWithUnfilledForm_SignupForm
) {
724 NavigateToFile("/password/password_fetch_submit.html");
726 // Need to pay attention for a message that Fetch has finished since there
727 // is no navigation to wait for.
728 content::DOMMessageQueue message_queue
;
730 // Verify that if Fetch without navigation occurs and the form has NOT been
731 // filled out we don't prompt.
732 scoped_ptr
<PromptObserver
> prompt_observer(
733 PromptObserver::Create(WebContents()));
734 std::string fill_and_submit
=
736 "document.getElementById('signup_username_field').value = 'temp';"
737 "document.getElementById('signup_submit_button').click();";
738 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
740 while (message_queue
.WaitForMessage(&message
)) {
741 if (message
== "\"FETCH_FINISHED\"")
745 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
748 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, NoPromptIfLinkClicked
) {
749 NavigateToFile("/password/password_form.html");
751 // Verify that if the user takes a direct action to leave the page, we don't
752 // prompt to save the password even if the form is already filled out.
753 NavigationObserver
observer(WebContents());
754 scoped_ptr
<PromptObserver
> prompt_observer(
755 PromptObserver::Create(WebContents()));
756 std::string fill_and_click_link
=
757 "document.getElementById('username_field').value = 'temp';"
758 "document.getElementById('password_field').value = 'random';"
759 "document.getElementById('link').click();";
760 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_click_link
));
762 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
765 // TODO(jam): http://crbug.com/350550
767 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
768 VerifyPasswordGenerationUpload
) {
769 // Prevent Autofill requests from actually going over the wire.
770 net::TestURLFetcherFactory factory
;
771 // Disable Autofill requesting access to AddressBook data. This causes
772 // the test to hang on Mac.
773 autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
775 // Visit a signup form.
776 NavigateToFile("/password/signup_form.html");
778 // Enter a password and save it.
779 NavigationObserver
first_observer(WebContents());
780 scoped_ptr
<PromptObserver
> prompt_observer(
781 PromptObserver::Create(WebContents()));
782 std::string fill_and_submit
=
783 "document.getElementById('other_info').value = 'stuff';"
784 "document.getElementById('username_field').value = 'my_username';"
785 "document.getElementById('password_field').value = 'password';"
786 "document.getElementById('input_submit_button').click()";
787 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
789 first_observer
.Wait();
790 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
791 prompt_observer
->Accept();
793 // Now navigate to a login form that has similar HTML markup.
794 NavigateToFile("/password/password_form.html");
796 // Simulate a user click to force an autofill of the form's DOM value, not
797 // just the suggested value.
798 content::SimulateMouseClick(
799 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
);
801 // The form should be filled with the previously submitted username.
802 std::string get_username
=
803 "window.domAutomationController.send("
804 "document.getElementById('username_field').value);";
805 std::string actual_username
;
806 ASSERT_TRUE(content::ExecuteScriptAndExtractString(RenderViewHost(),
809 ASSERT_EQ("my_username", actual_username
);
811 // Submit the form and verify that there is no infobar (as the password
812 // has already been saved).
813 NavigationObserver
second_observer(WebContents());
814 scoped_ptr
<PromptObserver
> second_prompt_observer(
815 PromptObserver::Create(WebContents()));
816 std::string submit_form
=
817 "document.getElementById('input_submit_button').click()";
818 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit_form
));
819 second_observer
.Wait();
820 EXPECT_FALSE(second_prompt_observer
->IsShowingPrompt());
822 // Verify that we sent two pings to Autofill. One vote for of PASSWORD for
823 // the current form, and one vote for ACCOUNT_CREATION_PASSWORD on the
824 // original form since it has more than 2 text input fields and was used for
825 // the first time on a different form.
826 base::HistogramBase
* upload_histogram
=
827 base::StatisticsRecorder::FindHistogram(
828 "PasswordGeneration.UploadStarted");
829 ASSERT_TRUE(upload_histogram
);
830 scoped_ptr
<base::HistogramSamples
> snapshot
=
831 upload_histogram
->SnapshotSamples();
832 EXPECT_EQ(0, snapshot
->GetCount(0 /* failure */));
833 EXPECT_EQ(2, snapshot
->GetCount(1 /* success */));
837 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
838 PromptForSubmitFromIframe
) {
839 NavigateToFile("/password/password_submit_from_iframe.html");
841 // Submit a form in an iframe, then cause the whole page to navigate without a
842 // user gesture. We expect the save password prompt to be shown here, because
843 // some pages use such iframes for login forms.
844 NavigationObserver
observer(WebContents());
845 scoped_ptr
<PromptObserver
> prompt_observer(
846 PromptObserver::Create(WebContents()));
847 std::string fill_and_submit
=
848 "var iframe = document.getElementById('test_iframe');"
849 "var iframe_doc = iframe.contentDocument;"
850 "iframe_doc.getElementById('username_field').value = 'temp';"
851 "iframe_doc.getElementById('password_field').value = 'random';"
852 "iframe_doc.getElementById('submit_button').click()";
854 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
856 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
859 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
860 PromptForInputElementWithoutName
) {
861 // Check that the prompt is shown for forms where input elements lack the
862 // "name" attribute but the "id" is present.
863 NavigateToFile("/password/password_form.html");
865 NavigationObserver
observer(WebContents());
866 scoped_ptr
<PromptObserver
> prompt_observer(
867 PromptObserver::Create(WebContents()));
868 std::string fill_and_submit
=
869 "document.getElementById('username_field_no_name').value = 'temp';"
870 "document.getElementById('password_field_no_name').value = 'random';"
871 "document.getElementById('input_submit_button_no_name').click()";
872 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
874 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
877 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
878 PromptForInputElementWithoutId
) {
879 // Check that the prompt is shown for forms where input elements lack the
880 // "id" attribute but the "name" attribute is present.
881 NavigateToFile("/password/password_form.html");
883 NavigationObserver
observer(WebContents());
884 scoped_ptr
<PromptObserver
> prompt_observer(
885 PromptObserver::Create(WebContents()));
886 std::string fill_and_submit
=
887 "document.getElementsByName('username_field_no_id')[0].value = 'temp';"
888 "document.getElementsByName('password_field_no_id')[0].value = 'random';"
889 "document.getElementsByName('input_submit_button_no_id')[0].click()";
890 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
892 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
895 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
896 NoPromptForInputElementWithoutIdAndName
) {
897 // Check that no prompt is shown for forms where the input fields lack both
898 // the "id" and the "name" attributes.
899 NavigateToFile("/password/password_form.html");
901 NavigationObserver
observer(WebContents());
902 scoped_ptr
<PromptObserver
> prompt_observer(
903 PromptObserver::Create(WebContents()));
904 std::string fill_and_submit
=
905 "var form = document.getElementById('testform_elements_no_id_no_name');"
906 "var username = form.children[0];"
907 "username.value = 'temp';"
908 "var password = form.children[1];"
909 "password.value = 'random';"
910 "form.children[2].click()"; // form.children[2] is the submit button.
911 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
913 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
916 // Test for checking that no prompt is shown for URLs with file: scheme.
917 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
918 NoPromptForFileSchemeURLs
) {
919 GURL url
= GetFileURL("password_form.html");
920 ui_test_utils::NavigateToURL(browser(), url
);
922 NavigationObserver
observer(WebContents());
923 scoped_ptr
<PromptObserver
> prompt_observer(
924 PromptObserver::Create(WebContents()));
925 std::string fill_and_submit
=
926 "document.getElementById('username_field').value = 'temp';"
927 "document.getElementById('password_field').value = 'random';"
928 "document.getElementById('input_submit_button').click();";
929 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
931 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
934 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
935 NoPromptForLandingPageWithHTTPErrorStatusCode
) {
936 // Check that no prompt is shown for forms where the landing page has
938 NavigateToFile("/password/password_form.html");
940 NavigationObserver
observer(WebContents());
941 scoped_ptr
<PromptObserver
> prompt_observer(
942 PromptObserver::Create(WebContents()));
943 std::string fill_and_submit
=
944 "document.getElementById('username_field_http_error').value = 'temp';"
945 "document.getElementById('password_field_http_error').value = 'random';"
946 "document.getElementById('input_submit_button_http_error').click()";
947 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
949 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
952 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
953 DeleteFrameBeforeSubmit
) {
954 NavigateToFile("/password/multi_frames.html");
956 NavigationObserver
observer(WebContents());
957 // Make sure we save some password info from an iframe and then destroy it.
958 std::string save_and_remove
=
959 "var first_frame = document.getElementById('first_frame');"
960 "var frame_doc = first_frame.contentDocument;"
961 "frame_doc.getElementById('username_field').value = 'temp';"
962 "frame_doc.getElementById('password_field').value = 'random';"
963 "frame_doc.getElementById('input_submit_button').click();"
964 "first_frame.parentNode.removeChild(first_frame);";
965 // Submit from the main frame, but without navigating through the onsubmit
967 std::string navigate_frame
=
968 "document.getElementById('username_field').value = 'temp';"
969 "document.getElementById('password_field').value = 'random';"
970 "document.getElementById('input_submit_button').click();"
971 "window.location.href = 'done.html';";
973 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), save_and_remove
));
974 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame
));
976 // The only thing we check here is that there is no use-after-free reported.
979 // Disabled on Windows due to flakiness: http://crbug.com/346297
981 #define MAYBE_PasswordValueAccessible DISABLED_PasswordValueAccessible
983 #define MAYBE_PasswordValueAccessible PasswordValueAccessible
985 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
986 MAYBE_PasswordValueAccessible
) {
987 NavigateToFile("/password/form_and_link.html");
989 // Click on a link to open a new tab, then switch back to the first one.
990 EXPECT_EQ(1, browser()->tab_strip_model()->count());
992 "document.getElementById('testlink').click();";
993 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), click
));
994 EXPECT_EQ(2, browser()->tab_strip_model()->count());
995 browser()->tab_strip_model()->ActivateTabAt(0, false);
997 // Fill in the credentials, and make sure they are saved.
998 NavigationObserver
form_submit_observer(WebContents());
999 scoped_ptr
<PromptObserver
> prompt_observer(
1000 PromptObserver::Create(WebContents()));
1001 std::string fill_and_submit
=
1002 "document.getElementById('username_field').value = 'temp';"
1003 "document.getElementById('password_field').value = 'random';"
1004 "document.getElementById('input_submit_button').click();";
1005 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1006 form_submit_observer
.Wait();
1007 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1008 prompt_observer
->Accept();
1010 // Reload the original page to have the saved credentials autofilled.
1011 NavigationObserver
reload_observer(WebContents());
1012 NavigateToFile("/password/form_and_link.html");
1013 reload_observer
.Wait();
1015 // Wait until the username is filled, to make sure autofill kicked in.
1016 WaitForElementValue("username_field", "temp");
1017 // Now check that the password is not accessible yet.
1018 CheckElementValue("password_field", "");
1019 // Let the user interact with the page.
1020 content::SimulateMouseClickAt(
1021 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(1, 1));
1022 // Wait until that interaction causes the password value to be revealed.
1023 WaitForElementValue("password_field", "random");
1024 // And check that after the side-effects of the interaction took place, the
1025 // username value stays the same.
1026 CheckElementValue("username_field", "temp");
1029 // The following test is limited to Aura, because
1030 // RenderWidgetHostViewGuest::ProcessAckedTouchEvent is, and
1031 // ProcessAckedTouchEvent is what triggers the translation of touch events to
1033 // Disabled: http://crbug.com/346297
1034 #if defined(USE_AURA)
1035 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1036 DISABLED_PasswordValueAccessibleOnSubmit
) {
1037 NavigateToFile("/password/form_and_link.html");
1039 // Fill in the credentials, and make sure they are saved.
1040 NavigationObserver
form_submit_observer(WebContents());
1041 scoped_ptr
<PromptObserver
> prompt_observer(
1042 PromptObserver::Create(WebContents()));
1043 std::string fill_and_submit
=
1044 "document.getElementById('username_field').value = 'temp';"
1045 "document.getElementById('password_field').value = 'random_secret';"
1046 "document.getElementById('input_submit_button').click();";
1047 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1048 form_submit_observer
.Wait();
1049 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1050 prompt_observer
->Accept();
1052 // Reload the original page to have the saved credentials autofilled.
1053 NavigationObserver
reload_observer(WebContents());
1054 NavigateToFile("/password/form_and_link.html");
1055 reload_observer
.Wait();
1057 NavigationObserver
submit_observer(WebContents());
1058 // Submit the form via a tap on the submit button. The button is placed at 0,
1059 // 100, and has height 300 and width 700.
1060 content::SimulateTapAt(WebContents(), gfx::Point(350, 250));
1061 submit_observer
.Wait();
1062 std::string query
= WebContents()->GetURL().query();
1063 EXPECT_NE(std::string::npos
, query
.find("random_secret")) << query
;
1067 // Test fix for crbug.com/338650.
1068 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1069 DontPromptForPasswordFormWithDefaultValue
) {
1070 NavigateToFile("/password/password_form_with_default_value.html");
1072 // Don't prompt if we navigate away even if there is a password value since
1073 // it's not coming from the user.
1074 NavigationObserver
observer(WebContents());
1075 scoped_ptr
<PromptObserver
> prompt_observer(
1076 PromptObserver::Create(WebContents()));
1077 NavigateToFile("/password/done.html");
1079 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1082 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1083 DontPromptForPasswordFormWithReadonlyPasswordField
) {
1084 NavigateToFile("/password/password_form_with_password_readonly.html");
1086 // Fill a form and submit through a <input type="submit"> button. Nothing
1088 NavigationObserver
observer(WebContents());
1089 scoped_ptr
<PromptObserver
> prompt_observer(
1090 PromptObserver::Create(WebContents()));
1091 std::string fill_and_submit
=
1092 "document.getElementById('username_field').value = 'temp';"
1093 "document.getElementById('password_field').value = 'random';"
1094 "document.getElementById('input_submit_button').click()";
1095 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1097 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1100 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1101 PromptWhenEnableAutomaticPasswordSavingSwitchIsNotSet
) {
1102 NavigateToFile("/password/password_form.html");
1104 // Fill a form and submit through a <input type="submit"> button.
1105 NavigationObserver
observer(WebContents());
1106 scoped_ptr
<PromptObserver
> prompt_observer(
1107 PromptObserver::Create(WebContents()));
1108 std::string fill_and_submit
=
1109 "document.getElementById('username_field').value = 'temp';"
1110 "document.getElementById('password_field').value = 'random';"
1111 "document.getElementById('input_submit_button').click()";
1112 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1114 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1117 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1118 DontPromptWhenEnableAutomaticPasswordSavingSwitchIsSet
) {
1119 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
1120 static_cast<password_manager::TestPasswordStore
*>(
1121 PasswordStoreFactory::GetForProfile(
1122 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
1124 EXPECT_TRUE(password_store
->IsEmpty());
1126 NavigateToFile("/password/password_form.html");
1128 // Add the enable-automatic-password-saving switch.
1129 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1130 password_manager::switches::kEnableAutomaticPasswordSaving
);
1132 // Fill a form and submit through a <input type="submit"> button.
1133 NavigationObserver
observer(WebContents());
1134 scoped_ptr
<PromptObserver
> prompt_observer(
1135 PromptObserver::Create(WebContents()));
1136 // Make sure that the only passwords saved are the auto-saved ones.
1137 std::string fill_and_submit
=
1138 "document.getElementById('username_field').value = 'temp';"
1139 "document.getElementById('password_field').value = 'random';"
1140 "document.getElementById('input_submit_button').click()";
1141 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1143 if (chrome::GetChannel() == version_info::Channel::UNKNOWN
) {
1144 // Passwords getting auto-saved, no prompt.
1145 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1146 EXPECT_FALSE(password_store
->IsEmpty());
1148 // Prompt shown, and no passwords saved automatically.
1149 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1150 EXPECT_TRUE(password_store
->IsEmpty());
1154 // Test fix for crbug.com/368690.
1155 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, NoPromptWhenReloading
) {
1156 NavigateToFile("/password/password_form.html");
1159 "document.getElementById('username_redirect').value = 'temp';"
1160 "document.getElementById('password_redirect').value = 'random';";
1161 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill
));
1163 NavigationObserver
observer(WebContents());
1164 scoped_ptr
<PromptObserver
> prompt_observer(
1165 PromptObserver::Create(WebContents()));
1166 GURL url
= embedded_test_server()->GetURL("/password/password_form.html");
1167 chrome::NavigateParams
params(browser(), url
, ::ui::PAGE_TRANSITION_RELOAD
);
1168 ui_test_utils::NavigateToURL(¶ms
);
1170 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1173 // Test that if a form gets dynamically added between the form parsing and
1174 // rendering, and while the main frame still loads, it still is registered, and
1175 // thus saving passwords from it works.
1176 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1177 FormsAddedBetweenParsingAndRendering
) {
1178 NavigateToFile("/password/between_parsing_and_rendering.html");
1180 NavigationObserver
observer(WebContents());
1181 scoped_ptr
<PromptObserver
> prompt_observer(
1182 PromptObserver::Create(WebContents()));
1183 std::string submit
=
1184 "document.getElementById('username').value = 'temp';"
1185 "document.getElementById('password').value = 'random';"
1186 "document.getElementById('submit-button').click();";
1187 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1190 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1193 // Test that if there was no previous page load then the PasswordManagerDriver
1194 // does not think that there were SSL errors on the current page. The test opens
1195 // a new tab with a URL for which the embedded test server issues a basic auth
1197 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, NoLastLoadGoodLastLoad
) {
1198 // Teach the embedded server to handle requests by issuing the basic auth
1200 embedded_test_server()->RegisterRequestHandler(
1201 base::Bind(&HandleTestAuthRequest
));
1203 LoginPromptBrowserTestObserver login_observer
;
1204 // We need to register to all sources, because the navigation observer we are
1205 // interested in is for a new tab to be opened, and thus does not exist yet.
1206 login_observer
.Register(content::NotificationService::AllSources());
1208 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
1209 static_cast<password_manager::TestPasswordStore
*>(
1210 PasswordStoreFactory::GetForProfile(
1211 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
1212 EXPECT_TRUE(password_store
->IsEmpty());
1214 // Navigate to a page requiring HTTP auth. Wait for the tab to get the correct
1215 // WebContents, but don't wait for navigation, which only finishes after
1217 ui_test_utils::NavigateToURLWithDisposition(
1219 embedded_test_server()->GetURL("/basic_auth"),
1221 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB
);
1223 content::NavigationController
* nav_controller
=
1224 &WebContents()->GetController();
1225 NavigationObserver
nav_observer(WebContents());
1226 scoped_ptr
<PromptObserver
> prompt_observer(
1227 PromptObserver::Create(WebContents()));
1228 WindowedAuthNeededObserver
auth_needed_observer(nav_controller
);
1229 auth_needed_observer
.Wait();
1231 WindowedAuthSuppliedObserver
auth_supplied_observer(nav_controller
);
1232 // Offer valid credentials on the auth challenge.
1233 ASSERT_EQ(1u, login_observer
.handlers().size());
1234 LoginHandler
* handler
= *login_observer
.handlers().begin();
1235 ASSERT_TRUE(handler
);
1236 // Any username/password will work.
1237 handler
->SetAuth(base::UTF8ToUTF16("user"), base::UTF8ToUTF16("pwd"));
1238 auth_supplied_observer
.Wait();
1240 // The password manager should be working correctly.
1241 nav_observer
.Wait();
1242 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1243 prompt_observer
->Accept();
1245 // Spin the message loop to make sure the password store had a chance to save
1247 base::RunLoop run_loop
;
1248 run_loop
.RunUntilIdle();
1249 EXPECT_FALSE(password_store
->IsEmpty());
1252 // In some situations, multiple PasswordFormManager instances from
1253 // PasswordManager::pending_login_managers_ would match (via DoesManage) a form
1254 // to be provisionally saved. One of them might be a complete match, the other
1255 // all-but-action match. Normally, the former should be preferred, but if the
1256 // former has not finished matching, and the latter has, the latter should be
1257 // used (otherwise we'd give up even though we could have saved the password).
1259 // Disabled on Mac and Linux due to flakiness: http://crbug.com/477812
1260 #if defined(OS_MACOSX) || defined(OS_LINUX)
1261 #define MAYBE_PreferPasswordFormManagerWhichFinishedMatching \
1262 DISABLED_PreferPasswordFormManagerWhichFinishedMatching
1264 #define MAYBE_PreferPasswordFormManagerWhichFinishedMatching \
1265 PreferPasswordFormManagerWhichFinishedMatching
1267 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1268 MAYBE_PreferPasswordFormManagerWhichFinishedMatching
) {
1269 NavigateToFile("/password/create_form_copy_on_submit.html");
1271 NavigationObserver
observer(WebContents());
1272 scoped_ptr
<PromptObserver
> prompt_observer(
1273 PromptObserver::Create(WebContents()));
1274 std::string submit
=
1275 "document.getElementById('username').value = 'overwrite_me';"
1276 "document.getElementById('password').value = 'random';"
1277 "document.getElementById('non-form-button').click();";
1278 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1281 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1284 // Test that if login fails and content server pushes a different login form
1285 // with action URL having different schemes. Heuristic shall be able
1286 // identify such cases and *shall not* prompt to save incorrect password.
1287 IN_PROC_BROWSER_TEST_F(
1288 PasswordManagerBrowserTestBase
,
1289 NoPromptForLoginFailedAndServerPushSeperateLoginForm_HttpToHttps
) {
1291 "/password/separate_login_form_with_onload_submit_script.html";
1292 GURL
http_url(embedded_test_server()->GetURL(path
));
1293 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1295 NavigationObserver
observer(WebContents());
1296 scoped_ptr
<PromptObserver
> prompt_observer(
1297 PromptObserver::Create(WebContents()));
1298 ui_test_utils::NavigateToURL(browser(), http_url
);
1300 observer
.SetPathToWaitFor("/password/done_and_separate_login_form.html");
1303 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1306 IN_PROC_BROWSER_TEST_F(
1307 PasswordManagerBrowserTestBase
,
1308 NoPromptForLoginFailedAndServerPushSeperateLoginForm_HttpsToHttp
) {
1309 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1310 ::switches::kAllowRunningInsecureContent
);
1311 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1312 ::switches::kIgnoreCertificateErrors
);
1313 const base::FilePath::CharType kDocRoot
[] =
1314 FILE_PATH_LITERAL("chrome/test/data");
1315 net::SpawnedTestServer
https_test_server(
1316 net::SpawnedTestServer::TYPE_HTTPS
,
1317 net::SpawnedTestServer::SSLOptions(
1318 net::SpawnedTestServer::SSLOptions::CERT_OK
),
1319 base::FilePath(kDocRoot
));
1320 ASSERT_TRUE(https_test_server
.Start());
1322 // This test case cannot inject the scripts via content::ExecuteScript() in
1323 // files served through HTTPS. Therefore the scripts are made part of the HTML
1324 // site and executed on load.
1326 "password/separate_login_form_with_onload_submit_script.html";
1327 GURL
https_url(https_test_server
.GetURL(path
));
1328 ASSERT_TRUE(https_url
.SchemeIs(url::kHttpsScheme
));
1330 NavigationObserver
observer(WebContents());
1331 scoped_ptr
<PromptObserver
> prompt_observer(
1332 PromptObserver::Create(WebContents()));
1333 ui_test_utils::NavigateToURL(browser(), https_url
);
1335 observer
.SetPathToWaitFor("/password/done_and_separate_login_form.html");
1338 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1341 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1342 PromptWhenPasswordFormWithoutUsernameFieldSubmitted
) {
1343 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
1344 static_cast<password_manager::TestPasswordStore
*>(
1345 PasswordStoreFactory::GetForProfile(
1346 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
1348 EXPECT_TRUE(password_store
->IsEmpty());
1350 NavigateToFile("/password/form_with_only_password_field.html");
1352 NavigationObserver
observer(WebContents());
1353 scoped_ptr
<PromptObserver
> prompt_observer(
1354 PromptObserver::Create(WebContents()));
1355 std::string submit
=
1356 "document.getElementById('password').value = 'password';"
1357 "document.getElementById('submit-button').click();";
1358 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1361 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1362 prompt_observer
->Accept();
1364 // Spin the message loop to make sure the password store had a chance to save
1366 base::RunLoop run_loop
;
1367 run_loop
.RunUntilIdle();
1368 EXPECT_FALSE(password_store
->IsEmpty());
1371 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1372 AutofillSuggetionsForPasswordFormWithoutUsernameField
) {
1373 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
1374 static_cast<password_manager::TestPasswordStore
*>(
1375 PasswordStoreFactory::GetForProfile(
1376 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
1378 EXPECT_TRUE(password_store
->IsEmpty());
1380 // Password form without username-field.
1381 NavigateToFile("/password/form_with_only_password_field.html");
1383 NavigationObserver
observer(WebContents());
1384 scoped_ptr
<PromptObserver
> prompt_observer(
1385 PromptObserver::Create(WebContents()));
1386 std::string submit
=
1387 "document.getElementById('password').value = 'mypassword';"
1388 "document.getElementById('submit-button').click();";
1389 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1392 prompt_observer
->Accept();
1394 // Spin the message loop to make sure the password store had a chance to save
1396 base::RunLoop run_loop
;
1397 run_loop
.RunUntilIdle();
1398 EXPECT_FALSE(password_store
->IsEmpty());
1400 // Now, navigate to same html password form and verify whether password is
1402 NavigateToFile("/password/form_with_only_password_field.html");
1404 // Let the user interact with the page, so that DOM gets modification events,
1405 // needed for autofilling fields.
1406 content::SimulateMouseClickAt(
1407 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(1, 1));
1409 // Wait until that interaction causes the password value to be revealed.
1410 WaitForElementValue("password", "mypassword");
1413 // Test that if a form gets autofilled, then it gets autofilled on re-creation
1415 // TODO(vabr): This is flaky everywhere. http://crbug.com/442704
1416 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1417 DISABLED_ReCreatedFormsGetFilled
) {
1418 NavigateToFile("/password/dynamic_password_form.html");
1420 // Fill in the credentials, and make sure they are saved.
1421 NavigationObserver
form_submit_observer(WebContents());
1422 scoped_ptr
<PromptObserver
> prompt_observer(
1423 PromptObserver::Create(WebContents()));
1424 std::string create_fill_and_submit
=
1425 "document.getElementById('create_form_button').click();"
1426 "window.setTimeout(function() {"
1427 " var form = document.getElementById('dynamic_form_id');"
1428 " form.username.value = 'temp';"
1429 " form.password.value = 'random';"
1432 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_fill_and_submit
));
1433 form_submit_observer
.Wait();
1434 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1435 prompt_observer
->Accept();
1437 // Reload the original page to have the saved credentials autofilled.
1438 NavigationObserver
reload_observer(WebContents());
1439 NavigateToFile("/password/dynamic_password_form.html");
1440 reload_observer
.Wait();
1441 std::string create_form
=
1442 "document.getElementById('create_form_button').click();";
1443 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_form
));
1444 // Wait until the username is filled, to make sure autofill kicked in.
1445 WaitForElementValue("username_id", "temp");
1447 // Now the form gets deleted and created again. It should get autofilled
1449 std::string delete_form
=
1450 "var form = document.getElementById('dynamic_form_id');"
1451 "form.parentNode.removeChild(form);";
1452 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), delete_form
));
1453 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_form
));
1454 WaitForElementValue("username_id", "temp");
1457 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1458 PromptForPushStateWhenFormDisappears
) {
1459 NavigateToFile("/password/password_push_state.html");
1461 // Verify that we show the save password prompt if 'history.pushState()'
1462 // is called after form submission is suppressed by, for example, calling
1463 // preventDefault() in a form's submit event handler.
1464 // Note that calling 'submit()' on a form with javascript doesn't call
1465 // the onsubmit handler, so we click the submit button instead.
1466 // Also note that the prompt will only show up if the form disappers
1468 NavigationObserver
observer(WebContents());
1469 observer
.set_quit_on_entry_committed(true);
1470 scoped_ptr
<PromptObserver
> prompt_observer(
1471 PromptObserver::Create(WebContents()));
1472 std::string fill_and_submit
=
1473 "document.getElementById('username_field').value = 'temp';"
1474 "document.getElementById('password_field').value = 'random';"
1475 "document.getElementById('submit_button').click()";
1476 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1478 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1481 // Similar to the case above, but this time the form persists after
1482 // 'history.pushState()'. And save password prompt should not show up
1484 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1485 NoPromptForPushStateWhenFormPersists
) {
1486 NavigateToFile("/password/password_push_state.html");
1488 // Set |should_delete_testform| to false to keep submitted form visible after
1489 // history.pushsTate();
1490 NavigationObserver
observer(WebContents());
1491 observer
.set_quit_on_entry_committed(true);
1492 scoped_ptr
<PromptObserver
> prompt_observer(
1493 PromptObserver::Create(WebContents()));
1494 std::string fill_and_submit
=
1495 "should_delete_testform = false;"
1496 "document.getElementById('username_field').value = 'temp';"
1497 "document.getElementById('password_field').value = 'random';"
1498 "document.getElementById('submit_button').click()";
1499 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1501 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1504 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1505 InFrameNavigationDoesNotClearPopupState
) {
1506 // Mock out the AutofillClient so we know how long to wait. Unfortunately
1507 // there isn't otherwise a good even to wait on to verify that the popup
1508 // would have been shown.
1509 password_manager::ContentPasswordManagerDriverFactory
* driver_factory
=
1510 password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
1512 ObservingAutofillClient observing_autofill_client
;
1513 driver_factory
->TestingSetDriverForFrame(
1514 RenderViewHost()->GetMainFrame(),
1515 make_scoped_ptr(new password_manager::ContentPasswordManagerDriver(
1516 RenderViewHost()->GetMainFrame(),
1517 ChromePasswordManagerClient::FromWebContents(WebContents()),
1518 &observing_autofill_client
)));
1520 NavigateToFile("/password/password_form.html");
1522 NavigationObserver
form_submit_observer(WebContents());
1523 scoped_ptr
<PromptObserver
> prompt_observer(
1524 PromptObserver::Create(WebContents()));
1526 "document.getElementById('username_field').value = 'temp';"
1527 "document.getElementById('password_field').value = 'random123';"
1528 "document.getElementById('input_submit_button').click();";
1530 // Save credentials for the site.
1531 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill
));
1532 form_submit_observer
.Wait();
1533 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1534 prompt_observer
->Accept();
1536 NavigateToFile("/password/password_form.html");
1537 ASSERT_TRUE(content::ExecuteScript(
1539 "var usernameRect = document.getElementById('username_field')"
1540 ".getBoundingClientRect();"));
1542 // Trigger in page navigation.
1543 std::string in_page_navigate
= "location.hash = '#blah';";
1544 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), in_page_navigate
));
1546 // Click on the username field to display the popup.
1548 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1550 "window.domAutomationController.send(usernameRect.top);",
1553 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1555 "window.domAutomationController.send(usernameRect.left);",
1558 content::SimulateMouseClickAt(
1559 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(left
+ 1,
1561 // Make sure the popup would be shown.
1562 observing_autofill_client
.Wait();
1565 // Passwords from change password forms should only be offered for saving when
1566 // it is certain that the username is correct.
1567 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, ChangePwdCorrect
) {
1568 NavigateToFile("/password/password_form.html");
1570 NavigationObserver
observer(WebContents());
1571 scoped_ptr
<PromptObserver
> prompt_observer(
1572 PromptObserver::Create(WebContents()));
1573 std::string fill_and_submit
=
1574 "document.getElementById('mark_chg_username_field').value = 'temp';"
1575 "document.getElementById('mark_chg_password_field').value = 'random';"
1576 "document.getElementById('mark_chg_new_password_1').value = 'random1';"
1577 "document.getElementById('mark_chg_new_password_2').value = 'random1';"
1578 "document.getElementById('mark_chg_submit_button').click()";
1579 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1581 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1584 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, ChangePwdIncorrect
) {
1585 NavigateToFile("/password/password_form.html");
1587 NavigationObserver
observer(WebContents());
1588 scoped_ptr
<PromptObserver
> prompt_observer(
1589 PromptObserver::Create(WebContents()));
1590 std::string fill_and_submit
=
1591 "document.getElementById('chg_not_username_field').value = 'temp';"
1592 "document.getElementById('chg_password_field').value = 'random';"
1593 "document.getElementById('chg_new_password_1').value = 'random1';"
1594 "document.getElementById('chg_new_password_2').value = 'random1';"
1595 "document.getElementById('chg_submit_button').click()";
1596 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1598 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1601 // As the two ChangePwd* tests above, only with submitting through
1602 // history.pushState().
1603 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1604 ChangePwdPushStateCorrect
) {
1605 NavigateToFile("/password/password_push_state.html");
1607 NavigationObserver
observer(WebContents());
1608 observer
.set_quit_on_entry_committed(true);
1609 scoped_ptr
<PromptObserver
> prompt_observer(
1610 PromptObserver::Create(WebContents()));
1611 std::string fill_and_submit
=
1612 "document.getElementById('mark_chg_username_field').value = 'temp';"
1613 "document.getElementById('mark_chg_password_field').value = 'random';"
1614 "document.getElementById('mark_chg_new_password_1').value = 'random1';"
1615 "document.getElementById('mark_chg_new_password_2').value = 'random1';"
1616 "document.getElementById('mark_chg_submit_button').click()";
1617 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1619 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1622 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1623 ChangePwdPushStateIncorrect
) {
1624 NavigateToFile("/password/password_push_state.html");
1626 NavigationObserver
observer(WebContents());
1627 observer
.set_quit_on_entry_committed(true);
1628 scoped_ptr
<PromptObserver
> prompt_observer(
1629 PromptObserver::Create(WebContents()));
1630 std::string fill_and_submit
=
1631 "document.getElementById('chg_not_username_field').value = 'temp';"
1632 "document.getElementById('chg_password_field').value = 'random';"
1633 "document.getElementById('chg_new_password_1').value = 'random1';"
1634 "document.getElementById('chg_new_password_2').value = 'random1';"
1635 "document.getElementById('chg_submit_button').click()";
1636 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1638 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1641 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
, NoPromptOnBack
) {
1642 // Go to a successful landing page through submitting first, so that it is
1643 // reachable through going back, and the remembered page transition is form
1644 // submit. There is no need to submit non-empty strings.
1645 NavigateToFile("/password/password_form.html");
1647 NavigationObserver
dummy_submit_observer(WebContents());
1648 std::string just_submit
=
1649 "document.getElementById('input_submit_button').click()";
1650 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), just_submit
));
1651 dummy_submit_observer
.Wait();
1653 // Now go to a page with a form again, fill the form, and go back instead of
1655 NavigateToFile("/password/dummy_submit.html");
1657 NavigationObserver
observer(WebContents());
1658 scoped_ptr
<PromptObserver
> prompt_observer(
1659 PromptObserver::Create(WebContents()));
1660 // The (dummy) submit is necessary to provisionally save the typed password. A
1661 // user typing in the password field would not need to submit to provisionally
1662 // save it, but the script cannot trigger that just by assigning to the
1664 std::string fill_and_back
=
1665 "document.getElementById('password_field').value = 'random';"
1666 "document.getElementById('input_submit_button').click();"
1667 "window.history.back();";
1668 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_back
));
1670 EXPECT_FALSE(prompt_observer
->IsShowingPrompt());
1673 // Regression test for http://crbug.com/452306
1674 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1675 ChangingTextToPasswordFieldOnSignupForm
) {
1676 NavigateToFile("/password/signup_form.html");
1678 // In this case, pretend that username_field is actually a password field
1679 // that starts as a text field to simulate placeholder.
1680 NavigationObserver
observer(WebContents());
1681 scoped_ptr
<PromptObserver
> prompt_observer(
1682 PromptObserver::Create(WebContents()));
1683 std::string change_and_submit
=
1684 "document.getElementById('other_info').value = 'username';"
1685 "document.getElementById('username_field').type = 'password';"
1686 "document.getElementById('username_field').value = 'mypass';"
1687 "document.getElementById('password_field').value = 'mypass';"
1688 "document.getElementById('testform').submit();";
1689 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), change_and_submit
));
1691 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1694 // Regression test for http://crbug.com/451631
1695 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1696 SavingOnManyPasswordFieldsTest
) {
1697 // Simulate Macy's registration page, which contains the normal 2 password
1698 // fields for confirming the new password plus 2 more fields for security
1699 // questions and credit card. Make sure that saving works correctly for such
1701 NavigateToFile("/password/many_password_signup_form.html");
1703 NavigationObserver
observer(WebContents());
1704 scoped_ptr
<PromptObserver
> prompt_observer(
1705 PromptObserver::Create(WebContents()));
1706 std::string fill_and_submit
=
1707 "document.getElementById('username_field').value = 'username';"
1708 "document.getElementById('password_field').value = 'mypass';"
1709 "document.getElementById('confirm_field').value = 'mypass';"
1710 "document.getElementById('security_answer').value = 'hometown';"
1711 "document.getElementById('SSN').value = '1234';"
1712 "document.getElementById('testform').submit();";
1713 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1715 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1718 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1719 SaveWhenIFrameDestroyedOnFormSubmit
) {
1720 NavigateToFile("/password/frame_detached_on_submit.html");
1722 // Need to pay attention for a message that XHR has finished since there
1723 // is no navigation to wait for.
1724 content::DOMMessageQueue message_queue
;
1726 scoped_ptr
<PromptObserver
> prompt_observer(
1727 PromptObserver::Create(WebContents()));
1728 std::string fill_and_submit
=
1729 "var iframe = document.getElementById('login_iframe');"
1730 "var frame_doc = iframe.contentDocument;"
1731 "frame_doc.getElementById('username_field').value = 'temp';"
1732 "frame_doc.getElementById('password_field').value = 'random';"
1733 "frame_doc.getElementById('submit_button').click();";
1735 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
1736 std::string message
;
1737 while (message_queue
.WaitForMessage(&message
)) {
1738 if (message
== "\"SUBMISSION_FINISHED\"")
1742 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1745 // Tests that if a site embeds the login and signup forms into one <form>, the
1746 // login form still gets autofilled.
1747 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1748 AutofillSuggetionsForLoginSignupForm
) {
1749 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
1750 static_cast<password_manager::TestPasswordStore
*>(
1751 PasswordStoreFactory::GetForProfile(
1752 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
1754 EXPECT_TRUE(password_store
->IsEmpty());
1756 NavigateToFile("/password/login_signup_form.html");
1758 NavigationObserver
observer(WebContents());
1759 scoped_ptr
<PromptObserver
> prompt_observer(
1760 PromptObserver::Create(WebContents()));
1761 std::string submit
=
1762 "document.getElementById('username').value = 'myusername';"
1763 "document.getElementById('password').value = 'mypassword';"
1764 "document.getElementById('submit').click();";
1765 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1768 prompt_observer
->Accept();
1770 // Spin the message loop to make sure the password store had a chance to save
1772 base::RunLoop run_loop
;
1773 run_loop
.RunUntilIdle();
1774 EXPECT_FALSE(password_store
->IsEmpty());
1776 // Now, navigate to the same html password form and verify whether password is
1778 NavigateToFile("/password/login_signup_form.html");
1780 // Let the user interact with the page, so that DOM gets modification events,
1781 // needed for autofilling fields.
1782 content::SimulateMouseClickAt(
1783 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(1, 1));
1785 // Wait until that interaction causes the password value to be revealed.
1786 WaitForElementValue("password", "mypassword");
1789 // Check that we can fill in cases where <base href> is set and the action of
1790 // the form is not set. Regression test for https://crbug.com/360230.
1791 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1792 BaseTagWithNoActionTest
) {
1793 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
1794 static_cast<password_manager::TestPasswordStore
*>(
1795 PasswordStoreFactory::GetForProfile(
1796 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
).get());
1798 EXPECT_TRUE(password_store
->IsEmpty());
1800 NavigateToFile("/password/password_xhr_submit.html");
1802 NavigationObserver
observer(WebContents());
1803 scoped_ptr
<PromptObserver
> prompt_observer(
1804 PromptObserver::Create(WebContents()));
1805 std::string submit
=
1806 "document.getElementById('username_field').value = 'myusername';"
1807 "document.getElementById('password_field').value = 'mypassword';"
1808 "document.getElementById('submit_button').click();";
1809 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1812 prompt_observer
->Accept();
1814 // Spin the message loop to make sure the password store had a chance to save
1816 base::RunLoop run_loop
;
1817 run_loop
.RunUntilIdle();
1818 EXPECT_FALSE(password_store
->IsEmpty());
1820 NavigateToFile("/password/password_xhr_submit.html");
1822 // Let the user interact with the page, so that DOM gets modification events,
1823 // needed for autofilling fields.
1824 content::SimulateMouseClickAt(
1825 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(1, 1));
1827 // Wait until that interaction causes the password value to be revealed.
1828 WaitForElementValue("password_field", "mypassword");
1831 // Check that a password form in an iframe of different origin will not be
1832 // filled in until a user interact with the form.
1833 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1834 CrossSiteIframeNotFillTest
) {
1835 // Setup the mock host resolver
1836 host_resolver()->AddRule("*", "127.0.0.1");
1838 // Here we need to dynamically create the iframe because the port
1839 // embedded_test_server ran on was dynamically allocated, so the iframe's src
1840 // attribute can only be determined at run time.
1841 NavigateToFile("/password/password_form_in_crosssite_iframe.html");
1842 NavigationObserver
ifrm_observer(WebContents());
1843 ifrm_observer
.SetPathToWaitFor("/password/crossite_iframe_content.html");
1844 std::string create_iframe
= base::StringPrintf(
1846 "'http://randomsite.net:%d/password/crossite_iframe_content.html');",
1847 embedded_test_server()->port());
1848 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_iframe
));
1849 ifrm_observer
.Wait();
1851 // Store a password for autofill later
1852 NavigationObserver
init_observer(WebContents());
1853 init_observer
.SetPathToWaitFor("/password/done.html");
1854 scoped_ptr
<PromptObserver
> prompt_observer(
1855 PromptObserver::Create(WebContents()));
1856 std::string init_form
= "sendMessage('fill_and_submit');";
1857 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), init_form
));
1858 init_observer
.Wait();
1859 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1860 prompt_observer
->Accept();
1862 // Visit the form again
1863 NavigationObserver
reload_observer(WebContents());
1864 NavigateToFile("/password/password_form_in_crosssite_iframe.html");
1865 reload_observer
.Wait();
1867 NavigationObserver
ifrm_observer_2(WebContents());
1868 ifrm_observer_2
.SetPathToWaitFor("/password/crossite_iframe_content.html");
1869 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_iframe
));
1870 ifrm_observer_2
.Wait();
1872 // Verify username is not autofilled
1873 std::string empty_username
;
1874 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1876 "sendMessage('get_username');",
1878 ASSERT_EQ("", empty_username
);
1879 // Verify password is not autofilled
1880 std::string empty_password
;
1881 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1883 "sendMessage('get_password');",
1885 ASSERT_EQ("", empty_password
);
1887 // Simulate the user interaction in the iframe and verify autofill is not
1888 // triggered. Note this check is only best-effort because we don't know how
1889 // long to wait before we are certain that no autofill will be triggered.
1890 // Theoretically unexpected autofill can happen after this check.
1891 ASSERT_TRUE(content::ExecuteScript(
1893 "var iframeRect = document.getElementById("
1894 "'iframe').getBoundingClientRect();"));
1896 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1898 "window.domAutomationController.send(iframeRect.top);",
1901 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1903 "window.domAutomationController.send(iframeRect.left);",
1906 content::SimulateMouseClickAt(
1907 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(left
+ 1,
1909 // Verify username is not autofilled
1910 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1912 "sendMessage('get_username');",
1914 ASSERT_EQ("", empty_username
);
1915 // Verify password is not autofilled
1916 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1918 "sendMessage('get_password');",
1920 ASSERT_EQ("", empty_password
);
1923 // Check that a password form in an iframe of same origin will not be
1924 // filled in until user interact with the iframe.
1925 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1926 SameOriginIframeAutoFillTest
) {
1927 // Visit the sign-up form to store a password for autofill later
1928 NavigateToFile("/password/password_form_in_same_origin_iframe.html");
1929 NavigationObserver
observer(WebContents());
1930 observer
.SetPathToWaitFor("/password/done.html");
1931 scoped_ptr
<PromptObserver
> prompt_observer(
1932 PromptObserver::Create(WebContents()));
1934 std::string submit
=
1935 "var ifrmDoc = document.getElementById('iframe').contentDocument;"
1936 "ifrmDoc.getElementById('username_field').value = 'temp';"
1937 "ifrmDoc.getElementById('password_field').value = 'pa55w0rd';"
1938 "ifrmDoc.getElementById('input_submit_button').click();";
1939 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit
));
1941 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
1942 prompt_observer
->Accept();
1944 // Visit the form again
1945 NavigationObserver
reload_observer(WebContents());
1946 NavigateToFile("/password/password_form_in_same_origin_iframe.html");
1947 reload_observer
.Wait();
1949 // Verify username is autofilled
1950 CheckElementValue("iframe", "username_field", "temp");
1952 // Verify password is not autofilled
1953 CheckElementValue("iframe", "password_field", "");
1955 // Simulate the user interaction in the iframe which should trigger autofill.
1956 ASSERT_TRUE(content::ExecuteScript(
1958 "var iframeRect = document.getElementById("
1959 "'iframe').getBoundingClientRect();"));
1961 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1963 "window.domAutomationController.send(iframeRect.top);",
1966 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1968 "window.domAutomationController.send(iframeRect.left);",
1971 content::SimulateMouseClickAt(
1972 WebContents(), 0, blink::WebMouseEvent::ButtonLeft
, gfx::Point(left
+ 1,
1974 // Verify password has been autofilled
1975 WaitForElementValue("iframe", "password_field", "pa55w0rd");
1977 // Verify username has been autofilled
1978 CheckElementValue("iframe", "username_field", "temp");
1982 // The password manager driver will kill processes when they try to access
1983 // passwords of sites other than the site the process is dedicated to, under
1985 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
1986 CrossSitePasswordEnforcement
) {
1987 // The code under test is only active under site isolation.
1988 if (!content::AreAllSitesIsolatedForTesting()) {
1992 // Setup the mock host resolver
1993 host_resolver()->AddRule("*", "127.0.0.1");
1995 // Navigate the main frame.
1996 GURL main_frame_url
= embedded_test_server()->GetURL(
1997 "/password/password_form_in_crosssite_iframe.html");
1998 NavigationObserver
observer(WebContents());
1999 ui_test_utils::NavigateToURL(browser(), main_frame_url
);
2002 // Create an iframe and navigate cross-site.
2003 NavigationObserver
iframe_observer(WebContents());
2004 iframe_observer
.SetPathToWaitFor("/password/crossite_iframe_content.html");
2005 GURL iframe_url
= embedded_test_server()->GetURL(
2006 "foo.com", "/password/crossite_iframe_content.html");
2007 std::string create_iframe
=
2008 base::StringPrintf("create_iframe('%s');", iframe_url
.spec().c_str());
2009 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_iframe
));
2010 iframe_observer
.Wait();
2012 // The iframe should get its own process.
2013 content::RenderFrameHost
* main_frame
= WebContents()->GetMainFrame();
2014 content::RenderFrameHost
* iframe
= iframe_observer
.render_frame_host();
2015 content::SiteInstance
* main_site_instance
= main_frame
->GetSiteInstance();
2016 content::SiteInstance
* iframe_site_instance
= iframe
->GetSiteInstance();
2017 EXPECT_NE(main_site_instance
, iframe_site_instance
);
2018 EXPECT_NE(main_frame
->GetProcess(), iframe
->GetProcess());
2020 // Try to get cross-site passwords from the subframe's process and wait for it
2022 std::vector
<autofill::PasswordForm
> password_forms
;
2023 password_forms
.push_back(autofill::PasswordForm());
2024 password_forms
.back().origin
= main_frame_url
;
2025 AutofillHostMsg_PasswordFormsParsed
illegal_forms_parsed(
2026 iframe
->GetRoutingID(), password_forms
);
2028 content::RenderProcessHostWatcher
iframe_killed(
2029 iframe
->GetProcess(),
2030 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
2032 IPC::IpcSecurityTestUtil::PwnMessageReceived(
2033 iframe
->GetProcess()->GetChannel(), illegal_forms_parsed
);
2035 iframe_killed
.Wait();
2038 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
2039 ChangePwdNoAccountStored
) {
2040 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
2041 NavigateToFile("/password/password_form.html");
2043 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2044 password_manager::switches::kEnablePasswordChangeSupport
);
2046 // Fill a form and submit through a <input type="submit"> button.
2047 NavigationObserver
observer(WebContents());
2048 scoped_ptr
<PromptObserver
> prompt_observer(
2049 PromptObserver::Create(WebContents()));
2051 std::string fill_and_submit
=
2052 "document.getElementById('chg_password_wo_username_field').value = "
2054 "document.getElementById('chg_new_password_wo_username_1').value = "
2056 "document.getElementById('chg_new_password_wo_username_2').value = "
2058 "document.getElementById('chg_submit_wo_username_button').click()";
2059 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
2061 // No credentials stored before, so save bubble is shown.
2062 EXPECT_TRUE(prompt_observer
->IsShowingPrompt());
2063 prompt_observer
->Accept();
2064 // Check that credentials are stored.
2065 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
2066 static_cast<password_manager::TestPasswordStore
*>(
2067 PasswordStoreFactory::GetForProfile(
2068 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
)
2070 // Spin the message loop to make sure the password store had a chance to save
2072 base::RunLoop run_loop
;
2073 run_loop
.RunUntilIdle();
2074 EXPECT_FALSE(password_store
->IsEmpty());
2075 CheckThatCredentialsStored(password_store
.get(), base::ASCIIToUTF16(""),
2076 base::ASCIIToUTF16("new_pw"));
2079 // TODO(dvadym): Turn on this test when Change password UI will be implemented
2080 // for Mac. http://crbug.com/359315
2081 #if !defined(OS_MACOSX)
2082 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
2083 ChangePwd1AccountStored
) {
2084 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
2085 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2086 password_manager::switches::kEnablePasswordChangeSupport
);
2087 // At first let us save credentials to the PasswordManager.
2088 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
2089 static_cast<password_manager::TestPasswordStore
*>(
2090 PasswordStoreFactory::GetForProfile(
2091 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
)
2093 autofill::PasswordForm signin_form
;
2094 signin_form
.signon_realm
= embedded_test_server()->base_url().spec();
2095 signin_form
.password_value
= base::ASCIIToUTF16("pw");
2096 signin_form
.username_value
= base::ASCIIToUTF16("temp");
2097 password_store
->AddLogin(signin_form
);
2099 // Check that password update bubble is shown.
2100 NavigateToFile("/password/password_form.html");
2101 NavigationObserver
observer(WebContents());
2102 scoped_ptr
<PromptObserver
> prompt_observer(
2103 PromptObserver::Create(WebContents()));
2104 std::string fill_and_submit_change_password
=
2105 "document.getElementById('chg_password_wo_username_field').value = "
2107 "document.getElementById('chg_new_password_wo_username_1').value = "
2109 "document.getElementById('chg_new_password_wo_username_2').value = "
2111 "document.getElementById('chg_submit_wo_username_button').click()";
2112 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
2113 fill_and_submit_change_password
));
2115 EXPECT_TRUE(prompt_observer
->IsShowingUpdatePrompt());
2117 const autofill::PasswordForm stored_form
=
2118 password_store
->stored_passwords().begin()->second
[0];
2119 prompt_observer
->AcceptUpdatePrompt(stored_form
);
2120 // Spin the message loop to make sure the password store had a chance to
2121 // update the password.
2122 base::RunLoop run_loop
;
2123 run_loop
.RunUntilIdle();
2124 CheckThatCredentialsStored(password_store
.get(), base::ASCIIToUTF16("temp"),
2125 base::ASCIIToUTF16("new_pw"));
2129 // TODO(dvadym): Turn on this test when Change password UI will be implemented
2130 // for Mac. http://crbug.com/359315
2131 #if !defined(OS_MACOSX)
2132 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
2133 PasswordOverridenUpdateBubbleShown
) {
2134 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
2135 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2136 password_manager::switches::kEnablePasswordChangeSupport
);
2137 // At first let us save credentials to the PasswordManager.
2138 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
2139 static_cast<password_manager::TestPasswordStore
*>(
2140 PasswordStoreFactory::GetForProfile(
2141 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
)
2143 autofill::PasswordForm signin_form
;
2144 signin_form
.signon_realm
= embedded_test_server()->base_url().spec();
2145 signin_form
.username_value
= base::ASCIIToUTF16("temp");
2146 signin_form
.password_value
= base::ASCIIToUTF16("pw");
2147 password_store
->AddLogin(signin_form
);
2149 // Check that password update bubble is shown.
2150 NavigateToFile("/password/password_form.html");
2151 NavigationObserver
observer(WebContents());
2152 scoped_ptr
<PromptObserver
> prompt_observer(
2153 PromptObserver::Create(WebContents()));
2154 std::string fill_and_submit
=
2155 "document.getElementById('username_field').value = 'temp';"
2156 "document.getElementById('password_field').value = 'new_pw';"
2157 "document.getElementById('input_submit_button').click()";
2158 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
2160 // The stored password "pw" was overriden with "new_pw", so update prompt is
2162 EXPECT_TRUE(prompt_observer
->IsShowingUpdatePrompt());
2164 const autofill::PasswordForm stored_form
=
2165 password_store
->stored_passwords().begin()->second
[0];
2166 prompt_observer
->AcceptUpdatePrompt(stored_form
);
2167 // Spin the message loop to make sure the password store had a chance to
2168 // update the password.
2169 base::RunLoop run_loop
;
2170 run_loop
.RunUntilIdle();
2171 CheckThatCredentialsStored(password_store
.get(), base::ASCIIToUTF16("temp"),
2172 base::ASCIIToUTF16("new_pw"));
2176 // TODO(dvadym): Turn on this test when Change password UI will be implemented
2177 // for Mac. http://crbug.com/359315
2178 #if !defined(OS_MACOSX)
2179 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase
,
2180 PasswordNotOverridenUpdateBubbleNotShown
) {
2181 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
2182 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2183 password_manager::switches::kEnablePasswordChangeSupport
);
2184 // At first let us save credentials to the PasswordManager.
2185 scoped_refptr
<password_manager::TestPasswordStore
> password_store
=
2186 static_cast<password_manager::TestPasswordStore
*>(
2187 PasswordStoreFactory::GetForProfile(
2188 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS
)
2190 autofill::PasswordForm signin_form
;
2191 signin_form
.signon_realm
= embedded_test_server()->base_url().spec();
2192 signin_form
.username_value
= base::ASCIIToUTF16("temp");
2193 signin_form
.password_value
= base::ASCIIToUTF16("pw");
2194 password_store
->AddLogin(signin_form
);
2196 // Check that password update bubble is shown.
2197 NavigateToFile("/password/password_form.html");
2198 NavigationObserver
observer(WebContents());
2199 scoped_ptr
<PromptObserver
> prompt_observer(
2200 PromptObserver::Create(WebContents()));
2201 std::string fill_and_submit
=
2202 "document.getElementById('username_field').value = 'temp';"
2203 "document.getElementById('password_field').value = 'pw';"
2204 "document.getElementById('input_submit_button').click()";
2205 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit
));
2207 // The stored password "pw" was not overriden, so update prompt is not
2209 EXPECT_FALSE(prompt_observer
->IsShowingUpdatePrompt());
2210 CheckThatCredentialsStored(password_store
.get(), base::ASCIIToUTF16("temp"),
2211 base::ASCIIToUTF16("pw"));
2215 } // namespace password_manager