Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / password_manager / password_manager_browsertest.cc
blob6cd24946f0a59b8d0f19edda16ce8966aad46b42
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.
5 #include <string>
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"
63 namespace {
65 GURL GetFileURL(const char* filename) {
66 base::FilePath path;
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();
88 } else {
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 {
99 public:
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();
114 private:
115 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
117 DISALLOW_COPY_AND_ASSIGN(ObservingAutofillClient);
120 // TODO(dvadym): This is for avoiding unused function compilation error. Remove
121 // it when http://crbug.com/359315 is implemented for Mac.
122 #if !defined(OS_MACOSX)
123 // For simplicity we assume that password store contains only 1 credentials.
124 void CheckThatCredentialsStored(
125 password_manager::TestPasswordStore* password_store,
126 const base::string16& username,
127 const base::string16& password) {
128 auto& passwords_map = password_store->stored_passwords();
129 ASSERT_EQ(1u, passwords_map.size());
130 auto& passwords_vector = passwords_map.begin()->second;
131 ASSERT_EQ(1u, passwords_vector.size());
132 const autofill::PasswordForm& form = passwords_vector[0];
133 EXPECT_EQ(username, form.username_value);
134 EXPECT_EQ(password, form.password_value);
136 #endif
138 } // namespace
140 namespace password_manager {
142 // Actual tests ---------------------------------------------------------------
143 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, PromptForNormalSubmit) {
144 NavigateToFile("/password/password_form.html");
146 // Fill a form and submit through a <input type="submit"> button. Nothing
147 // special.
148 NavigationObserver observer(WebContents());
149 scoped_ptr<PromptObserver> prompt_observer(
150 PromptObserver::Create(WebContents()));
151 std::string fill_and_submit =
152 "document.getElementById('username_field').value = 'temp';"
153 "document.getElementById('password_field').value = 'random';"
154 "document.getElementById('input_submit_button').click()";
155 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
156 observer.Wait();
157 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
160 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
161 PromptForSubmitWithInPageNavigation) {
162 NavigateToFile("/password/password_navigate_before_submit.html");
164 // Fill a form and submit through a <input type="submit"> button. Nothing
165 // special. The form does an in-page navigation before submitting.
166 NavigationObserver observer(WebContents());
167 scoped_ptr<PromptObserver> prompt_observer(
168 PromptObserver::Create(WebContents()));
169 std::string fill_and_submit =
170 "document.getElementById('username_field').value = 'temp';"
171 "document.getElementById('password_field').value = 'random';"
172 "document.getElementById('input_submit_button').click()";
173 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
174 observer.Wait();
175 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
178 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
179 LoginSuccessWithUnrelatedForm) {
180 // Log in, see a form on the landing page. That form is not related to the
181 // login form (=has a different action), so we should offer saving the
182 // password.
183 NavigateToFile("/password/password_form.html");
185 NavigationObserver observer(WebContents());
186 scoped_ptr<PromptObserver> prompt_observer(
187 PromptObserver::Create(WebContents()));
188 std::string fill_and_submit =
189 "document.getElementById('username_unrelated').value = 'temp';"
190 "document.getElementById('password_unrelated').value = 'random';"
191 "document.getElementById('submit_unrelated').click()";
192 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
193 observer.Wait();
194 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
197 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, LoginFailed) {
198 // Log in, see a form on the landing page. That form is not related to the
199 // login form (=has a different action), so we should offer saving the
200 // password.
201 NavigateToFile("/password/password_form.html");
203 NavigationObserver observer(WebContents());
204 scoped_ptr<PromptObserver> prompt_observer(
205 PromptObserver::Create(WebContents()));
206 std::string fill_and_submit =
207 "document.getElementById('username_failed').value = 'temp';"
208 "document.getElementById('password_failed').value = 'random';"
209 "document.getElementById('submit_failed').click()";
210 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
211 observer.Wait();
212 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
215 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, Redirects) {
216 NavigateToFile("/password/password_form.html");
218 // Fill a form and submit through a <input type="submit"> button. The form
219 // points to a redirection page.
220 NavigationObserver observer(WebContents());
221 scoped_ptr<PromptObserver> prompt_observer(
222 PromptObserver::Create(WebContents()));
223 std::string fill_and_submit =
224 "document.getElementById('username_redirect').value = 'temp';"
225 "document.getElementById('password_redirect').value = 'random';"
226 "document.getElementById('submit_redirect').click()";
227 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
228 observer.Wait();
229 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
231 // The redirection page now redirects via Javascript. We check that the
232 // infobar stays.
233 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
234 "window.location.href = 'done.html';"));
235 observer.Wait();
236 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
239 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
240 PromptForSubmitUsingJavaScript) {
241 NavigateToFile("/password/password_form.html");
243 // Fill a form and submit using <button> that calls submit() on the form.
244 // This should work regardless of the type of element, as long as submit() is
245 // called.
246 NavigationObserver observer(WebContents());
247 scoped_ptr<PromptObserver> prompt_observer(
248 PromptObserver::Create(WebContents()));
249 std::string fill_and_submit =
250 "document.getElementById('username_field').value = 'temp';"
251 "document.getElementById('password_field').value = 'random';"
252 "document.getElementById('submit_button').click()";
253 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
254 observer.Wait();
255 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
258 // Flaky: crbug.com/301547, observed on win and mac. Probably happens on all
259 // platforms.
260 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
261 DISABLED_PromptForDynamicForm) {
262 NavigateToFile("/password/dynamic_password_form.html");
264 // Fill the dynamic password form and submit.
265 NavigationObserver observer(WebContents());
266 scoped_ptr<PromptObserver> prompt_observer(
267 PromptObserver::Create(WebContents()));
268 std::string fill_and_submit =
269 "document.getElementById('create_form_button').click();"
270 "window.setTimeout(function() {"
271 " document.dynamic_form.username.value = 'tempro';"
272 " document.dynamic_form.password.value = 'random';"
273 " document.dynamic_form.submit();"
274 "}, 0)";
275 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
276 observer.Wait();
277 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
280 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoPromptForNavigation) {
281 NavigateToFile("/password/password_form.html");
283 // Don't fill the password form, just navigate away. Shouldn't prompt.
284 NavigationObserver observer(WebContents());
285 scoped_ptr<PromptObserver> prompt_observer(
286 PromptObserver::Create(WebContents()));
287 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
288 "window.location.href = 'done.html';"));
289 observer.Wait();
290 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
293 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
294 NoPromptForSubFrameNavigation) {
295 NavigateToFile("/password/multi_frames.html");
297 // If you are filling out a password form in one frame and a different frame
298 // navigates, this should not trigger the infobar.
299 NavigationObserver observer(WebContents());
300 scoped_ptr<PromptObserver> prompt_observer(
301 PromptObserver::Create(WebContents()));
302 observer.SetPathToWaitFor("/password/done.html");
303 std::string fill =
304 "var first_frame = document.getElementById('first_frame');"
305 "var frame_doc = first_frame.contentDocument;"
306 "frame_doc.getElementById('username_field').value = 'temp';"
307 "frame_doc.getElementById('password_field').value = 'random';";
308 std::string navigate_frame =
309 "var second_iframe = document.getElementById('second_frame');"
310 "second_iframe.contentWindow.location.href = 'done.html';";
312 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill));
313 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame));
314 observer.Wait();
315 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
318 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
319 PromptAfterSubmitWithSubFrameNavigation) {
320 NavigateToFile("/password/multi_frames.html");
322 // Make sure that we prompt to save password even if a sub-frame navigation
323 // happens first.
324 NavigationObserver observer(WebContents());
325 scoped_ptr<PromptObserver> prompt_observer(
326 PromptObserver::Create(WebContents()));
327 observer.SetPathToWaitFor("/password/done.html");
328 std::string navigate_frame =
329 "var second_iframe = document.getElementById('second_frame');"
330 "second_iframe.contentWindow.location.href = 'other.html';";
331 std::string fill_and_submit =
332 "var first_frame = document.getElementById('first_frame');"
333 "var frame_doc = first_frame.contentDocument;"
334 "frame_doc.getElementById('username_field').value = 'temp';"
335 "frame_doc.getElementById('password_field').value = 'random';"
336 "frame_doc.getElementById('input_submit_button').click();";
338 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame));
339 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
340 observer.Wait();
341 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
344 IN_PROC_BROWSER_TEST_F(
345 PasswordManagerBrowserTestBase,
346 NoPromptForFailedLoginFromMainFrameWithMultiFramesInPage) {
347 NavigateToFile("/password/multi_frames.html");
349 // Make sure that we don't prompt to save the password for a failed login
350 // from the main frame with multiple frames in the same page.
351 NavigationObserver observer(WebContents());
352 scoped_ptr<PromptObserver> prompt_observer(
353 PromptObserver::Create(WebContents()));
354 std::string fill_and_submit =
355 "document.getElementById('username_failed').value = 'temp';"
356 "document.getElementById('password_failed').value = 'random';"
357 "document.getElementById('submit_failed').click();";
359 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
360 observer.Wait();
361 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
364 // Disabled on Mac due to flakiness: crbug.com/493263
365 #if defined(OS_MACOSX)
366 #define MAYBE_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage \
367 DISABLED_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage
368 #else
369 #define MAYBE_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage \
370 NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage
371 #endif
372 IN_PROC_BROWSER_TEST_F(
373 PasswordManagerBrowserTestBase,
374 MAYBE_NoPromptForFailedLoginFromSubFrameWithMultiFramesInPage) {
375 NavigateToFile("/password/multi_frames.html");
377 // Make sure that we don't prompt to save the password for a failed login
378 // from a sub-frame with multiple frames in the same page.
379 NavigationObserver observer(WebContents());
380 scoped_ptr<PromptObserver> prompt_observer(
381 PromptObserver::Create(WebContents()));
382 std::string fill_and_submit =
383 "var first_frame = document.getElementById('first_frame');"
384 "var frame_doc = first_frame.contentDocument;"
385 "frame_doc.getElementById('username_failed').value = 'temp';"
386 "frame_doc.getElementById('password_failed').value = 'random';"
387 "frame_doc.getElementById('submit_failed').click();";
389 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
390 observer.SetPathToWaitFor("/password/failed.html");
391 observer.Wait();
392 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
395 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, PromptForXHRSubmit) {
396 #if defined(OS_WIN) && defined(USE_ASH)
397 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
398 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
399 ::switches::kAshBrowserTests))
400 return;
401 #endif
402 NavigateToFile("/password/password_xhr_submit.html");
404 // Verify that we show the save password prompt if a form returns false
405 // in its onsubmit handler but instead logs in/navigates via XHR.
406 // Note that calling 'submit()' on a form with javascript doesn't call
407 // the onsubmit handler, so we click the submit button instead.
408 NavigationObserver observer(WebContents());
409 scoped_ptr<PromptObserver> prompt_observer(
410 PromptObserver::Create(WebContents()));
411 std::string fill_and_submit =
412 "document.getElementById('username_field').value = 'temp';"
413 "document.getElementById('password_field').value = 'random';"
414 "document.getElementById('submit_button').click()";
415 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
416 observer.Wait();
417 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
420 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
421 PromptForXHRWithoutOnSubmit) {
422 NavigateToFile("/password/password_xhr_submit.html");
424 // Verify that if XHR navigation occurs and the form is properly filled out,
425 // we try and save the password even though onsubmit hasn't been called.
426 NavigationObserver observer(WebContents());
427 scoped_ptr<PromptObserver> prompt_observer(
428 PromptObserver::Create(WebContents()));
429 std::string fill_and_navigate =
430 "document.getElementById('username_field').value = 'temp';"
431 "document.getElementById('password_field').value = 'random';"
432 "send_xhr()";
433 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
434 observer.Wait();
435 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
438 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
439 PromptForXHRWithNewPasswordsWithoutOnSubmit) {
440 NavigateToFile("/password/password_xhr_submit.html");
442 // Verify that if XHR navigation occurs and the form is properly filled out,
443 // we try and save the password even though onsubmit hasn't been called.
444 // Specifically verify that the password form saving new passwords is treated
445 // the same as a login form.
446 NavigationObserver observer(WebContents());
447 scoped_ptr<PromptObserver> prompt_observer(
448 PromptObserver::Create(WebContents()));
449 std::string fill_and_navigate =
450 "document.getElementById('signup_username_field').value = 'temp';"
451 "document.getElementById('signup_password_field').value = 'random';"
452 "document.getElementById('confirmation_password_field').value = 'random';"
453 "send_xhr()";
454 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
455 observer.Wait();
456 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
459 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
460 PromptForXHRSubmitWithoutNavigation) {
461 NavigateToFile("/password/password_xhr_submit.html");
463 // Need to pay attention for a message that XHR has finished since there
464 // is no navigation to wait for.
465 content::DOMMessageQueue message_queue;
467 // Verify that if XHR without navigation occurs and the form has been filled
468 // out we try and save the password. Note that in general the submission
469 // doesn't need to be via form.submit(), but for testing purposes it's
470 // necessary since we otherwise ignore changes made to the value of these
471 // fields by script.
472 scoped_ptr<PromptObserver> prompt_observer(
473 PromptObserver::Create(WebContents()));
474 std::string fill_and_submit =
475 "navigate = false;"
476 "document.getElementById('username_field').value = 'temp';"
477 "document.getElementById('password_field').value = 'random';"
478 "document.getElementById('submit_button').click();";
479 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
480 std::string message;
481 while (message_queue.WaitForMessage(&message)) {
482 if (message == "\"XHR_FINISHED\"")
483 break;
486 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
489 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
490 PromptForXHRSubmitWithoutNavigation_SignupForm) {
491 NavigateToFile("/password/password_xhr_submit.html");
493 // Need to pay attention for a message that XHR has finished since there
494 // is no navigation to wait for.
495 content::DOMMessageQueue message_queue;
497 // Verify that if XHR without navigation occurs and the form has been filled
498 // out we try and save the password. Note that in general the submission
499 // doesn't need to be via form.submit(), but for testing purposes it's
500 // necessary since we otherwise ignore changes made to the value of these
501 // fields by script.
502 scoped_ptr<PromptObserver> prompt_observer(
503 PromptObserver::Create(WebContents()));
504 std::string fill_and_submit =
505 "navigate = false;"
506 "document.getElementById('signup_username_field').value = 'temp';"
507 "document.getElementById('signup_password_field').value = 'random';"
508 "document.getElementById('confirmation_password_field').value = 'random';"
509 "document.getElementById('signup_submit_button').click();";
510 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
511 std::string message;
512 while (message_queue.WaitForMessage(&message)) {
513 if (message == "\"XHR_FINISHED\"")
514 break;
517 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
520 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
521 NoPromptForXHRSubmitWithoutNavigationWithUnfilledForm) {
522 NavigateToFile("/password/password_xhr_submit.html");
524 // Need to pay attention for a message that XHR has finished since there
525 // is no navigation to wait for.
526 content::DOMMessageQueue message_queue;
528 // Verify that if XHR without navigation occurs and the form has NOT been
529 // filled out we don't prompt.
530 scoped_ptr<PromptObserver> prompt_observer(
531 PromptObserver::Create(WebContents()));
532 std::string fill_and_submit =
533 "navigate = false;"
534 "document.getElementById('username_field').value = 'temp';"
535 "document.getElementById('submit_button').click();";
536 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
537 std::string message;
538 while (message_queue.WaitForMessage(&message)) {
539 if (message == "\"XHR_FINISHED\"")
540 break;
543 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
546 IN_PROC_BROWSER_TEST_F(
547 PasswordManagerBrowserTestBase,
548 NoPromptForXHRSubmitWithoutNavigationWithUnfilledForm_SignupForm) {
549 NavigateToFile("/password/password_xhr_submit.html");
551 // Need to pay attention for a message that XHR has finished since there
552 // is no navigation to wait for.
553 content::DOMMessageQueue message_queue;
555 // Verify that if XHR without navigation occurs and the form has NOT been
556 // filled out we don't prompt.
557 scoped_ptr<PromptObserver> prompt_observer(
558 PromptObserver::Create(WebContents()));
559 std::string fill_and_submit =
560 "navigate = false;"
561 "document.getElementById('signup_username_field').value = 'temp';"
562 "document.getElementById('signup_submit_button').click();";
563 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
564 std::string message;
565 while (message_queue.WaitForMessage(&message)) {
566 if (message == "\"XHR_FINISHED\"")
567 break;
570 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
573 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, PromptForFetchSubmit) {
574 #if defined(OS_WIN) && defined(USE_ASH)
575 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
576 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
577 ::switches::kAshBrowserTests))
578 return;
579 #endif
580 NavigateToFile("/password/password_fetch_submit.html");
582 // Verify that we show the save password prompt if a form returns false
583 // in its onsubmit handler but instead logs in/navigates via Fetch.
584 // Note that calling 'submit()' on a form with javascript doesn't call
585 // the onsubmit handler, so we click the submit button instead.
586 NavigationObserver observer(WebContents());
587 scoped_ptr<PromptObserver> prompt_observer(
588 PromptObserver::Create(WebContents()));
589 std::string fill_and_submit =
590 "document.getElementById('username_field').value = 'temp';"
591 "document.getElementById('password_field').value = 'random';"
592 "document.getElementById('submit_button').click()";
593 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
594 observer.Wait();
595 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
598 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
599 PromptForFetchWithoutOnSubmit) {
600 NavigateToFile("/password/password_fetch_submit.html");
602 // Verify that if Fetch navigation occurs and the form is properly filled out,
603 // we try and save the password even though onsubmit hasn't been called.
604 NavigationObserver observer(WebContents());
605 scoped_ptr<PromptObserver> prompt_observer(
606 PromptObserver::Create(WebContents()));
607 std::string fill_and_navigate =
608 "document.getElementById('username_field').value = 'temp';"
609 "document.getElementById('password_field').value = 'random';"
610 "send_fetch()";
611 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
612 observer.Wait();
613 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
616 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
617 PromptForFetchWithNewPasswordsWithoutOnSubmit) {
618 NavigateToFile("/password/password_fetch_submit.html");
620 // Verify that if Fetch navigation occurs and the form is properly filled out,
621 // we try and save the password even though onsubmit hasn't been called.
622 // Specifically verify that the password form saving new passwords is treated
623 // the same as a login form.
624 NavigationObserver observer(WebContents());
625 scoped_ptr<PromptObserver> prompt_observer(
626 PromptObserver::Create(WebContents()));
627 std::string fill_and_navigate =
628 "document.getElementById('signup_username_field').value = 'temp';"
629 "document.getElementById('signup_password_field').value = 'random';"
630 "document.getElementById('confirmation_password_field').value = 'random';"
631 "send_fetch()";
632 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
633 observer.Wait();
634 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
637 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
638 PromptForFetchSubmitWithoutNavigation) {
639 NavigateToFile("/password/password_fetch_submit.html");
641 // Need to pay attention for a message that XHR has finished since there
642 // is no navigation to wait for.
643 content::DOMMessageQueue message_queue;
645 // Verify that if XHR without navigation occurs and the form has been filled
646 // out we try and save the password. Note that in general the submission
647 // doesn't need to be via form.submit(), but for testing purposes it's
648 // necessary since we otherwise ignore changes made to the value of these
649 // fields by script.
650 scoped_ptr<PromptObserver> prompt_observer(
651 PromptObserver::Create(WebContents()));
652 std::string fill_and_submit =
653 "navigate = false;"
654 "document.getElementById('username_field').value = 'temp';"
655 "document.getElementById('password_field').value = 'random';"
656 "document.getElementById('submit_button').click();";
657 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
658 std::string message;
659 while (message_queue.WaitForMessage(&message)) {
660 if (message == "\"FETCH_FINISHED\"")
661 break;
664 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
667 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
668 PromptForFetchSubmitWithoutNavigation_SignupForm) {
669 NavigateToFile("/password/password_fetch_submit.html");
671 // Need to pay attention for a message that Fetch has finished since there
672 // is no navigation to wait for.
673 content::DOMMessageQueue message_queue;
675 // Verify that if Fetch without navigation occurs and the form has been filled
676 // out we try and save the password. Note that in general the submission
677 // doesn't need to be via form.submit(), but for testing purposes it's
678 // necessary since we otherwise ignore changes made to the value of these
679 // fields by script.
680 scoped_ptr<PromptObserver> prompt_observer(
681 PromptObserver::Create(WebContents()));
682 std::string fill_and_submit =
683 "navigate = false;"
684 "document.getElementById('signup_username_field').value = 'temp';"
685 "document.getElementById('signup_password_field').value = 'random';"
686 "document.getElementById('confirmation_password_field').value = 'random';"
687 "document.getElementById('signup_submit_button').click();";
688 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
689 std::string message;
690 while (message_queue.WaitForMessage(&message)) {
691 if (message == "\"FETCH_FINISHED\"")
692 break;
695 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
698 IN_PROC_BROWSER_TEST_F(
699 PasswordManagerBrowserTestBase,
700 NoPromptForFetchSubmitWithoutNavigationWithUnfilledForm) {
701 NavigateToFile("/password/password_fetch_submit.html");
703 // Need to pay attention for a message that Fetch has finished since there
704 // is no navigation to wait for.
705 content::DOMMessageQueue message_queue;
707 // Verify that if Fetch without navigation occurs and the form has NOT been
708 // filled out we don't prompt.
709 scoped_ptr<PromptObserver> prompt_observer(
710 PromptObserver::Create(WebContents()));
711 std::string fill_and_submit =
712 "navigate = false;"
713 "document.getElementById('username_field').value = 'temp';"
714 "document.getElementById('submit_button').click();";
715 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
716 std::string message;
717 while (message_queue.WaitForMessage(&message)) {
718 if (message == "\"FETCH_FINISHED\"")
719 break;
722 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
725 IN_PROC_BROWSER_TEST_F(
726 PasswordManagerBrowserTestBase,
727 NoPromptForFetchSubmitWithoutNavigationWithUnfilledForm_SignupForm) {
728 NavigateToFile("/password/password_fetch_submit.html");
730 // Need to pay attention for a message that Fetch has finished since there
731 // is no navigation to wait for.
732 content::DOMMessageQueue message_queue;
734 // Verify that if Fetch without navigation occurs and the form has NOT been
735 // filled out we don't prompt.
736 scoped_ptr<PromptObserver> prompt_observer(
737 PromptObserver::Create(WebContents()));
738 std::string fill_and_submit =
739 "navigate = false;"
740 "document.getElementById('signup_username_field').value = 'temp';"
741 "document.getElementById('signup_submit_button').click();";
742 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
743 std::string message;
744 while (message_queue.WaitForMessage(&message)) {
745 if (message == "\"FETCH_FINISHED\"")
746 break;
749 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
752 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoPromptIfLinkClicked) {
753 NavigateToFile("/password/password_form.html");
755 // Verify that if the user takes a direct action to leave the page, we don't
756 // prompt to save the password even if the form is already filled out.
757 NavigationObserver observer(WebContents());
758 scoped_ptr<PromptObserver> prompt_observer(
759 PromptObserver::Create(WebContents()));
760 std::string fill_and_click_link =
761 "document.getElementById('username_field').value = 'temp';"
762 "document.getElementById('password_field').value = 'random';"
763 "document.getElementById('link').click();";
764 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_click_link));
765 observer.Wait();
766 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
769 // TODO(jam): http://crbug.com/350550
770 #if !defined(OS_WIN)
771 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
772 VerifyPasswordGenerationUpload) {
773 // Prevent Autofill requests from actually going over the wire.
774 net::TestURLFetcherFactory factory;
775 // Disable Autofill requesting access to AddressBook data. This causes
776 // the test to hang on Mac.
777 autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
779 // Visit a signup form.
780 NavigateToFile("/password/signup_form.html");
782 // Enter a password and save it.
783 NavigationObserver first_observer(WebContents());
784 scoped_ptr<PromptObserver> prompt_observer(
785 PromptObserver::Create(WebContents()));
786 std::string fill_and_submit =
787 "document.getElementById('other_info').value = 'stuff';"
788 "document.getElementById('username_field').value = 'my_username';"
789 "document.getElementById('password_field').value = 'password';"
790 "document.getElementById('input_submit_button').click()";
791 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
793 first_observer.Wait();
794 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
795 prompt_observer->Accept();
797 // Now navigate to a login form that has similar HTML markup.
798 NavigateToFile("/password/password_form.html");
800 // Simulate a user click to force an autofill of the form's DOM value, not
801 // just the suggested value.
802 content::SimulateMouseClick(
803 WebContents(), 0, blink::WebMouseEvent::ButtonLeft);
805 // The form should be filled with the previously submitted username.
806 std::string get_username =
807 "window.domAutomationController.send("
808 "document.getElementById('username_field').value);";
809 std::string actual_username;
810 ASSERT_TRUE(content::ExecuteScriptAndExtractString(RenderViewHost(),
811 get_username,
812 &actual_username));
813 ASSERT_EQ("my_username", actual_username);
815 // Submit the form and verify that there is no infobar (as the password
816 // has already been saved).
817 NavigationObserver second_observer(WebContents());
818 scoped_ptr<PromptObserver> second_prompt_observer(
819 PromptObserver::Create(WebContents()));
820 std::string submit_form =
821 "document.getElementById('input_submit_button').click()";
822 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit_form));
823 second_observer.Wait();
824 EXPECT_FALSE(second_prompt_observer->IsShowingPrompt());
826 // Verify that we sent two pings to Autofill. One vote for of PASSWORD for
827 // the current form, and one vote for ACCOUNT_CREATION_PASSWORD on the
828 // original form since it has more than 2 text input fields and was used for
829 // the first time on a different form.
830 base::HistogramBase* upload_histogram =
831 base::StatisticsRecorder::FindHistogram(
832 "PasswordGeneration.UploadStarted");
833 ASSERT_TRUE(upload_histogram);
834 scoped_ptr<base::HistogramSamples> snapshot =
835 upload_histogram->SnapshotSamples();
836 EXPECT_EQ(0, snapshot->GetCount(0 /* failure */));
837 EXPECT_EQ(2, snapshot->GetCount(1 /* success */));
839 #endif
841 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
842 PromptForSubmitFromIframe) {
843 NavigateToFile("/password/password_submit_from_iframe.html");
845 // Submit a form in an iframe, then cause the whole page to navigate without a
846 // user gesture. We expect the save password prompt to be shown here, because
847 // some pages use such iframes for login forms.
848 NavigationObserver observer(WebContents());
849 scoped_ptr<PromptObserver> prompt_observer(
850 PromptObserver::Create(WebContents()));
851 std::string fill_and_submit =
852 "var iframe = document.getElementById('test_iframe');"
853 "var iframe_doc = iframe.contentDocument;"
854 "iframe_doc.getElementById('username_field').value = 'temp';"
855 "iframe_doc.getElementById('password_field').value = 'random';"
856 "iframe_doc.getElementById('submit_button').click()";
858 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
859 observer.Wait();
860 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
863 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
864 PromptForInputElementWithoutName) {
865 // Check that the prompt is shown for forms where input elements lack the
866 // "name" attribute but the "id" is present.
867 NavigateToFile("/password/password_form.html");
869 NavigationObserver observer(WebContents());
870 scoped_ptr<PromptObserver> prompt_observer(
871 PromptObserver::Create(WebContents()));
872 std::string fill_and_submit =
873 "document.getElementById('username_field_no_name').value = 'temp';"
874 "document.getElementById('password_field_no_name').value = 'random';"
875 "document.getElementById('input_submit_button_no_name').click()";
876 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
877 observer.Wait();
878 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
881 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
882 PromptForInputElementWithoutId) {
883 // Check that the prompt is shown for forms where input elements lack the
884 // "id" attribute but the "name" attribute is present.
885 NavigateToFile("/password/password_form.html");
887 NavigationObserver observer(WebContents());
888 scoped_ptr<PromptObserver> prompt_observer(
889 PromptObserver::Create(WebContents()));
890 std::string fill_and_submit =
891 "document.getElementsByName('username_field_no_id')[0].value = 'temp';"
892 "document.getElementsByName('password_field_no_id')[0].value = 'random';"
893 "document.getElementsByName('input_submit_button_no_id')[0].click()";
894 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
895 observer.Wait();
896 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
899 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
900 NoPromptForInputElementWithoutIdAndName) {
901 // Check that no prompt is shown for forms where the input fields lack both
902 // the "id" and the "name" attributes.
903 NavigateToFile("/password/password_form.html");
905 NavigationObserver observer(WebContents());
906 scoped_ptr<PromptObserver> prompt_observer(
907 PromptObserver::Create(WebContents()));
908 std::string fill_and_submit =
909 "var form = document.getElementById('testform_elements_no_id_no_name');"
910 "var username = form.children[0];"
911 "username.value = 'temp';"
912 "var password = form.children[1];"
913 "password.value = 'random';"
914 "form.children[2].click()"; // form.children[2] is the submit button.
915 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
916 observer.Wait();
917 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
920 // Test for checking that no prompt is shown for URLs with file: scheme.
921 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
922 NoPromptForFileSchemeURLs) {
923 GURL url = GetFileURL("password_form.html");
924 ui_test_utils::NavigateToURL(browser(), url);
926 NavigationObserver observer(WebContents());
927 scoped_ptr<PromptObserver> prompt_observer(
928 PromptObserver::Create(WebContents()));
929 std::string fill_and_submit =
930 "document.getElementById('username_field').value = 'temp';"
931 "document.getElementById('password_field').value = 'random';"
932 "document.getElementById('input_submit_button').click();";
933 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
934 observer.Wait();
935 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
938 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
939 NoPromptForLandingPageWithHTTPErrorStatusCode) {
940 // Check that no prompt is shown for forms where the landing page has
941 // HTTP status 404.
942 NavigateToFile("/password/password_form.html");
944 NavigationObserver observer(WebContents());
945 scoped_ptr<PromptObserver> prompt_observer(
946 PromptObserver::Create(WebContents()));
947 std::string fill_and_submit =
948 "document.getElementById('username_field_http_error').value = 'temp';"
949 "document.getElementById('password_field_http_error').value = 'random';"
950 "document.getElementById('input_submit_button_http_error').click()";
951 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
952 observer.Wait();
953 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
956 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
957 DeleteFrameBeforeSubmit) {
958 NavigateToFile("/password/multi_frames.html");
960 NavigationObserver observer(WebContents());
961 // Make sure we save some password info from an iframe and then destroy it.
962 std::string save_and_remove =
963 "var first_frame = document.getElementById('first_frame');"
964 "var frame_doc = first_frame.contentDocument;"
965 "frame_doc.getElementById('username_field').value = 'temp';"
966 "frame_doc.getElementById('password_field').value = 'random';"
967 "frame_doc.getElementById('input_submit_button').click();"
968 "first_frame.parentNode.removeChild(first_frame);";
969 // Submit from the main frame, but without navigating through the onsubmit
970 // handler.
971 std::string navigate_frame =
972 "document.getElementById('username_field').value = 'temp';"
973 "document.getElementById('password_field').value = 'random';"
974 "document.getElementById('input_submit_button').click();"
975 "window.location.href = 'done.html';";
977 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), save_and_remove));
978 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), navigate_frame));
979 observer.Wait();
980 // The only thing we check here is that there is no use-after-free reported.
983 // Disabled on Windows due to flakiness: http://crbug.com/346297
984 #if defined(OS_WIN)
985 #define MAYBE_PasswordValueAccessible DISABLED_PasswordValueAccessible
986 #else
987 #define MAYBE_PasswordValueAccessible PasswordValueAccessible
988 #endif
989 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
990 MAYBE_PasswordValueAccessible) {
991 NavigateToFile("/password/form_and_link.html");
993 // Click on a link to open a new tab, then switch back to the first one.
994 EXPECT_EQ(1, browser()->tab_strip_model()->count());
995 std::string click =
996 "document.getElementById('testlink').click();";
997 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), click));
998 EXPECT_EQ(2, browser()->tab_strip_model()->count());
999 browser()->tab_strip_model()->ActivateTabAt(0, false);
1001 // Fill in the credentials, and make sure they are saved.
1002 NavigationObserver form_submit_observer(WebContents());
1003 scoped_ptr<PromptObserver> prompt_observer(
1004 PromptObserver::Create(WebContents()));
1005 std::string fill_and_submit =
1006 "document.getElementById('username_field').value = 'temp';"
1007 "document.getElementById('password_field').value = 'random';"
1008 "document.getElementById('input_submit_button').click();";
1009 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1010 form_submit_observer.Wait();
1011 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1012 prompt_observer->Accept();
1014 // Reload the original page to have the saved credentials autofilled.
1015 NavigationObserver reload_observer(WebContents());
1016 NavigateToFile("/password/form_and_link.html");
1017 reload_observer.Wait();
1019 // Wait until the username is filled, to make sure autofill kicked in.
1020 WaitForElementValue("username_field", "temp");
1021 // Now check that the password is not accessible yet.
1022 CheckElementValue("password_field", "");
1023 // Let the user interact with the page.
1024 content::SimulateMouseClickAt(
1025 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
1026 // Wait until that interaction causes the password value to be revealed.
1027 WaitForElementValue("password_field", "random");
1028 // And check that after the side-effects of the interaction took place, the
1029 // username value stays the same.
1030 CheckElementValue("username_field", "temp");
1033 // The following test is limited to Aura, because
1034 // RenderWidgetHostViewGuest::ProcessAckedTouchEvent is, and
1035 // ProcessAckedTouchEvent is what triggers the translation of touch events to
1036 // gesture events.
1037 // Disabled: http://crbug.com/346297
1038 #if defined(USE_AURA)
1039 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1040 DISABLED_PasswordValueAccessibleOnSubmit) {
1041 NavigateToFile("/password/form_and_link.html");
1043 // Fill in the credentials, and make sure they are saved.
1044 NavigationObserver form_submit_observer(WebContents());
1045 scoped_ptr<PromptObserver> prompt_observer(
1046 PromptObserver::Create(WebContents()));
1047 std::string fill_and_submit =
1048 "document.getElementById('username_field').value = 'temp';"
1049 "document.getElementById('password_field').value = 'random_secret';"
1050 "document.getElementById('input_submit_button').click();";
1051 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1052 form_submit_observer.Wait();
1053 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1054 prompt_observer->Accept();
1056 // Reload the original page to have the saved credentials autofilled.
1057 NavigationObserver reload_observer(WebContents());
1058 NavigateToFile("/password/form_and_link.html");
1059 reload_observer.Wait();
1061 NavigationObserver submit_observer(WebContents());
1062 // Submit the form via a tap on the submit button. The button is placed at 0,
1063 // 100, and has height 300 and width 700.
1064 content::SimulateTapAt(WebContents(), gfx::Point(350, 250));
1065 submit_observer.Wait();
1066 std::string query = WebContents()->GetURL().query();
1067 EXPECT_NE(std::string::npos, query.find("random_secret")) << query;
1069 #endif
1071 // Test fix for crbug.com/338650.
1072 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1073 DontPromptForPasswordFormWithDefaultValue) {
1074 NavigateToFile("/password/password_form_with_default_value.html");
1076 // Don't prompt if we navigate away even if there is a password value since
1077 // it's not coming from the user.
1078 NavigationObserver observer(WebContents());
1079 scoped_ptr<PromptObserver> prompt_observer(
1080 PromptObserver::Create(WebContents()));
1081 NavigateToFile("/password/done.html");
1082 observer.Wait();
1083 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1086 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1087 DontPromptForPasswordFormWithReadonlyPasswordField) {
1088 NavigateToFile("/password/password_form_with_password_readonly.html");
1090 // Fill a form and submit through a <input type="submit"> button. Nothing
1091 // special.
1092 NavigationObserver observer(WebContents());
1093 scoped_ptr<PromptObserver> prompt_observer(
1094 PromptObserver::Create(WebContents()));
1095 std::string fill_and_submit =
1096 "document.getElementById('username_field').value = 'temp';"
1097 "document.getElementById('password_field').value = 'random';"
1098 "document.getElementById('input_submit_button').click()";
1099 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1100 observer.Wait();
1101 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1104 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1105 PromptWhenEnableAutomaticPasswordSavingSwitchIsNotSet) {
1106 NavigateToFile("/password/password_form.html");
1108 // Fill a form and submit through a <input type="submit"> button.
1109 NavigationObserver observer(WebContents());
1110 scoped_ptr<PromptObserver> prompt_observer(
1111 PromptObserver::Create(WebContents()));
1112 std::string fill_and_submit =
1113 "document.getElementById('username_field').value = 'temp';"
1114 "document.getElementById('password_field').value = 'random';"
1115 "document.getElementById('input_submit_button').click()";
1116 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1117 observer.Wait();
1118 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1121 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1122 DontPromptWhenEnableAutomaticPasswordSavingSwitchIsSet) {
1123 scoped_refptr<password_manager::TestPasswordStore> password_store =
1124 static_cast<password_manager::TestPasswordStore*>(
1125 PasswordStoreFactory::GetForProfile(
1126 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get());
1128 EXPECT_TRUE(password_store->IsEmpty());
1130 NavigateToFile("/password/password_form.html");
1132 // Add the enable-automatic-password-saving switch.
1133 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1134 password_manager::switches::kEnableAutomaticPasswordSaving);
1136 // Fill a form and submit through a <input type="submit"> button.
1137 NavigationObserver observer(WebContents());
1138 scoped_ptr<PromptObserver> prompt_observer(
1139 PromptObserver::Create(WebContents()));
1140 // Make sure that the only passwords saved are the auto-saved ones.
1141 std::string fill_and_submit =
1142 "document.getElementById('username_field').value = 'temp';"
1143 "document.getElementById('password_field').value = 'random';"
1144 "document.getElementById('input_submit_button').click()";
1145 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1146 observer.Wait();
1147 if (chrome::GetChannel() == version_info::Channel::UNKNOWN) {
1148 // Passwords getting auto-saved, no prompt.
1149 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1150 EXPECT_FALSE(password_store->IsEmpty());
1151 } else {
1152 // Prompt shown, and no passwords saved automatically.
1153 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1154 EXPECT_TRUE(password_store->IsEmpty());
1158 // Test fix for crbug.com/368690.
1159 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoPromptWhenReloading) {
1160 NavigateToFile("/password/password_form.html");
1162 std::string fill =
1163 "document.getElementById('username_redirect').value = 'temp';"
1164 "document.getElementById('password_redirect').value = 'random';";
1165 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill));
1167 NavigationObserver observer(WebContents());
1168 scoped_ptr<PromptObserver> prompt_observer(
1169 PromptObserver::Create(WebContents()));
1170 GURL url = embedded_test_server()->GetURL("/password/password_form.html");
1171 chrome::NavigateParams params(browser(), url, ::ui::PAGE_TRANSITION_RELOAD);
1172 ui_test_utils::NavigateToURL(&params);
1173 observer.Wait();
1174 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1177 // Test that if a form gets dynamically added between the form parsing and
1178 // rendering, and while the main frame still loads, it still is registered, and
1179 // thus saving passwords from it works.
1180 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1181 FormsAddedBetweenParsingAndRendering) {
1182 NavigateToFile("/password/between_parsing_and_rendering.html");
1184 NavigationObserver observer(WebContents());
1185 scoped_ptr<PromptObserver> prompt_observer(
1186 PromptObserver::Create(WebContents()));
1187 std::string submit =
1188 "document.getElementById('username').value = 'temp';"
1189 "document.getElementById('password').value = 'random';"
1190 "document.getElementById('submit-button').click();";
1191 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit));
1192 observer.Wait();
1194 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1197 // Test that if there was no previous page load then the PasswordManagerDriver
1198 // does not think that there were SSL errors on the current page. The test opens
1199 // a new tab with a URL for which the embedded test server issues a basic auth
1200 // challenge.
1201 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoLastLoadGoodLastLoad) {
1202 // Teach the embedded server to handle requests by issuing the basic auth
1203 // challenge.
1204 embedded_test_server()->RegisterRequestHandler(
1205 base::Bind(&HandleTestAuthRequest));
1207 LoginPromptBrowserTestObserver login_observer;
1208 // We need to register to all sources, because the navigation observer we are
1209 // interested in is for a new tab to be opened, and thus does not exist yet.
1210 login_observer.Register(content::NotificationService::AllSources());
1212 scoped_refptr<password_manager::TestPasswordStore> password_store =
1213 static_cast<password_manager::TestPasswordStore*>(
1214 PasswordStoreFactory::GetForProfile(
1215 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get());
1216 EXPECT_TRUE(password_store->IsEmpty());
1218 // Navigate to a page requiring HTTP auth. Wait for the tab to get the correct
1219 // WebContents, but don't wait for navigation, which only finishes after
1220 // authentication.
1221 ui_test_utils::NavigateToURLWithDisposition(
1222 browser(),
1223 embedded_test_server()->GetURL("/basic_auth"),
1224 NEW_FOREGROUND_TAB,
1225 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
1227 content::NavigationController* nav_controller =
1228 &WebContents()->GetController();
1229 NavigationObserver nav_observer(WebContents());
1230 scoped_ptr<PromptObserver> prompt_observer(
1231 PromptObserver::Create(WebContents()));
1232 WindowedAuthNeededObserver auth_needed_observer(nav_controller);
1233 auth_needed_observer.Wait();
1235 WindowedAuthSuppliedObserver auth_supplied_observer(nav_controller);
1236 // Offer valid credentials on the auth challenge.
1237 ASSERT_EQ(1u, login_observer.handlers().size());
1238 LoginHandler* handler = *login_observer.handlers().begin();
1239 ASSERT_TRUE(handler);
1240 // Any username/password will work.
1241 handler->SetAuth(base::UTF8ToUTF16("user"), base::UTF8ToUTF16("pwd"));
1242 auth_supplied_observer.Wait();
1244 // The password manager should be working correctly.
1245 nav_observer.Wait();
1246 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1247 prompt_observer->Accept();
1249 // Spin the message loop to make sure the password store had a chance to save
1250 // the password.
1251 base::RunLoop run_loop;
1252 run_loop.RunUntilIdle();
1253 EXPECT_FALSE(password_store->IsEmpty());
1256 // In some situations, multiple PasswordFormManager instances from
1257 // PasswordManager::pending_login_managers_ would match (via DoesManage) a form
1258 // to be provisionally saved. One of them might be a complete match, the other
1259 // all-but-action match. Normally, the former should be preferred, but if the
1260 // former has not finished matching, and the latter has, the latter should be
1261 // used (otherwise we'd give up even though we could have saved the password).
1263 // Disabled on Mac and Linux due to flakiness: http://crbug.com/477812
1264 #if defined(OS_MACOSX) || defined(OS_LINUX)
1265 #define MAYBE_PreferPasswordFormManagerWhichFinishedMatching \
1266 DISABLED_PreferPasswordFormManagerWhichFinishedMatching
1267 #else
1268 #define MAYBE_PreferPasswordFormManagerWhichFinishedMatching \
1269 PreferPasswordFormManagerWhichFinishedMatching
1270 #endif
1271 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1272 MAYBE_PreferPasswordFormManagerWhichFinishedMatching) {
1273 NavigateToFile("/password/create_form_copy_on_submit.html");
1275 NavigationObserver observer(WebContents());
1276 scoped_ptr<PromptObserver> prompt_observer(
1277 PromptObserver::Create(WebContents()));
1278 std::string submit =
1279 "document.getElementById('username').value = 'overwrite_me';"
1280 "document.getElementById('password').value = 'random';"
1281 "document.getElementById('non-form-button').click();";
1282 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit));
1283 observer.Wait();
1285 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1288 // Test that if login fails and content server pushes a different login form
1289 // with action URL having different schemes. Heuristic shall be able
1290 // identify such cases and *shall not* prompt to save incorrect password.
1291 IN_PROC_BROWSER_TEST_F(
1292 PasswordManagerBrowserTestBase,
1293 NoPromptForLoginFailedAndServerPushSeperateLoginForm_HttpToHttps) {
1294 std::string path =
1295 "/password/separate_login_form_with_onload_submit_script.html";
1296 GURL http_url(embedded_test_server()->GetURL(path));
1297 ASSERT_TRUE(http_url.SchemeIs(url::kHttpScheme));
1299 NavigationObserver observer(WebContents());
1300 scoped_ptr<PromptObserver> prompt_observer(
1301 PromptObserver::Create(WebContents()));
1302 ui_test_utils::NavigateToURL(browser(), http_url);
1304 observer.SetPathToWaitFor("/password/done_and_separate_login_form.html");
1305 observer.Wait();
1307 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1310 IN_PROC_BROWSER_TEST_F(
1311 PasswordManagerBrowserTestBase,
1312 NoPromptForLoginFailedAndServerPushSeperateLoginForm_HttpsToHttp) {
1313 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1314 ::switches::kAllowRunningInsecureContent);
1315 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1316 ::switches::kIgnoreCertificateErrors);
1317 const base::FilePath::CharType kDocRoot[] =
1318 FILE_PATH_LITERAL("chrome/test/data");
1319 net::SpawnedTestServer https_test_server(
1320 net::SpawnedTestServer::TYPE_HTTPS,
1321 net::SpawnedTestServer::SSLOptions(
1322 net::SpawnedTestServer::SSLOptions::CERT_OK),
1323 base::FilePath(kDocRoot));
1324 ASSERT_TRUE(https_test_server.Start());
1326 // This test case cannot inject the scripts via content::ExecuteScript() in
1327 // files served through HTTPS. Therefore the scripts are made part of the HTML
1328 // site and executed on load.
1329 std::string path =
1330 "password/separate_login_form_with_onload_submit_script.html";
1331 GURL https_url(https_test_server.GetURL(path));
1332 ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme));
1334 NavigationObserver observer(WebContents());
1335 scoped_ptr<PromptObserver> prompt_observer(
1336 PromptObserver::Create(WebContents()));
1337 ui_test_utils::NavigateToURL(browser(), https_url);
1339 observer.SetPathToWaitFor("/password/done_and_separate_login_form.html");
1340 observer.Wait();
1342 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1345 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1346 PromptWhenPasswordFormWithoutUsernameFieldSubmitted) {
1347 scoped_refptr<password_manager::TestPasswordStore> password_store =
1348 static_cast<password_manager::TestPasswordStore*>(
1349 PasswordStoreFactory::GetForProfile(
1350 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get());
1352 EXPECT_TRUE(password_store->IsEmpty());
1354 NavigateToFile("/password/form_with_only_password_field.html");
1356 NavigationObserver observer(WebContents());
1357 scoped_ptr<PromptObserver> prompt_observer(
1358 PromptObserver::Create(WebContents()));
1359 std::string submit =
1360 "document.getElementById('password').value = 'password';"
1361 "document.getElementById('submit-button').click();";
1362 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit));
1363 observer.Wait();
1365 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1366 prompt_observer->Accept();
1368 // Spin the message loop to make sure the password store had a chance to save
1369 // the password.
1370 base::RunLoop run_loop;
1371 run_loop.RunUntilIdle();
1372 EXPECT_FALSE(password_store->IsEmpty());
1375 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1376 AutofillSuggetionsForPasswordFormWithoutUsernameField) {
1377 std::string submit =
1378 "document.getElementById('password').value = 'mypassword';"
1379 "document.getElementById('submit-button').click();";
1380 VerifyPasswordIsSavedAndFilled("/password/form_with_only_password_field.html",
1381 submit, "password", "mypassword");
1384 // Test that if a form gets autofilled, then it gets autofilled on re-creation
1385 // as well.
1386 // TODO(vabr): This is flaky everywhere. http://crbug.com/442704
1387 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1388 DISABLED_ReCreatedFormsGetFilled) {
1389 NavigateToFile("/password/dynamic_password_form.html");
1391 // Fill in the credentials, and make sure they are saved.
1392 NavigationObserver form_submit_observer(WebContents());
1393 scoped_ptr<PromptObserver> prompt_observer(
1394 PromptObserver::Create(WebContents()));
1395 std::string create_fill_and_submit =
1396 "document.getElementById('create_form_button').click();"
1397 "window.setTimeout(function() {"
1398 " var form = document.getElementById('dynamic_form_id');"
1399 " form.username.value = 'temp';"
1400 " form.password.value = 'random';"
1401 " form.submit();"
1402 "}, 0)";
1403 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_fill_and_submit));
1404 form_submit_observer.Wait();
1405 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1406 prompt_observer->Accept();
1408 // Reload the original page to have the saved credentials autofilled.
1409 NavigationObserver reload_observer(WebContents());
1410 NavigateToFile("/password/dynamic_password_form.html");
1411 reload_observer.Wait();
1412 std::string create_form =
1413 "document.getElementById('create_form_button').click();";
1414 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_form));
1415 // Wait until the username is filled, to make sure autofill kicked in.
1416 WaitForElementValue("username_id", "temp");
1418 // Now the form gets deleted and created again. It should get autofilled
1419 // again.
1420 std::string delete_form =
1421 "var form = document.getElementById('dynamic_form_id');"
1422 "form.parentNode.removeChild(form);";
1423 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), delete_form));
1424 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_form));
1425 WaitForElementValue("username_id", "temp");
1428 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1429 PromptForPushStateWhenFormDisappears) {
1430 NavigateToFile("/password/password_push_state.html");
1432 // Verify that we show the save password prompt if 'history.pushState()'
1433 // is called after form submission is suppressed by, for example, calling
1434 // preventDefault() in a form's submit event handler.
1435 // Note that calling 'submit()' on a form with javascript doesn't call
1436 // the onsubmit handler, so we click the submit button instead.
1437 // Also note that the prompt will only show up if the form disappers
1438 // after submission
1439 NavigationObserver observer(WebContents());
1440 observer.set_quit_on_entry_committed(true);
1441 scoped_ptr<PromptObserver> prompt_observer(
1442 PromptObserver::Create(WebContents()));
1443 std::string fill_and_submit =
1444 "document.getElementById('username_field').value = 'temp';"
1445 "document.getElementById('password_field').value = 'random';"
1446 "document.getElementById('submit_button').click()";
1447 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1448 observer.Wait();
1449 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1452 // Similar to the case above, but this time the form persists after
1453 // 'history.pushState()'. And save password prompt should not show up
1454 // in this case.
1455 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1456 NoPromptForPushStateWhenFormPersists) {
1457 NavigateToFile("/password/password_push_state.html");
1459 // Set |should_delete_testform| to false to keep submitted form visible after
1460 // history.pushsTate();
1461 NavigationObserver observer(WebContents());
1462 observer.set_quit_on_entry_committed(true);
1463 scoped_ptr<PromptObserver> prompt_observer(
1464 PromptObserver::Create(WebContents()));
1465 std::string fill_and_submit =
1466 "should_delete_testform = false;"
1467 "document.getElementById('username_field').value = 'temp';"
1468 "document.getElementById('password_field').value = 'random';"
1469 "document.getElementById('submit_button').click()";
1470 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1471 observer.Wait();
1472 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1475 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1476 InFrameNavigationDoesNotClearPopupState) {
1477 // Mock out the AutofillClient so we know how long to wait. Unfortunately
1478 // there isn't otherwise a good even to wait on to verify that the popup
1479 // would have been shown.
1480 password_manager::ContentPasswordManagerDriverFactory* driver_factory =
1481 password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
1482 WebContents());
1483 ObservingAutofillClient observing_autofill_client;
1484 driver_factory->TestingSetDriverForFrame(
1485 RenderViewHost()->GetMainFrame(),
1486 make_scoped_ptr(new password_manager::ContentPasswordManagerDriver(
1487 RenderViewHost()->GetMainFrame(),
1488 ChromePasswordManagerClient::FromWebContents(WebContents()),
1489 &observing_autofill_client)));
1491 NavigateToFile("/password/password_form.html");
1493 NavigationObserver form_submit_observer(WebContents());
1494 scoped_ptr<PromptObserver> prompt_observer(
1495 PromptObserver::Create(WebContents()));
1496 std::string fill =
1497 "document.getElementById('username_field').value = 'temp';"
1498 "document.getElementById('password_field').value = 'random123';"
1499 "document.getElementById('input_submit_button').click();";
1501 // Save credentials for the site.
1502 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill));
1503 form_submit_observer.Wait();
1504 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1505 prompt_observer->Accept();
1507 NavigateToFile("/password/password_form.html");
1508 ASSERT_TRUE(content::ExecuteScript(
1509 RenderViewHost(),
1510 "var usernameRect = document.getElementById('username_field')"
1511 ".getBoundingClientRect();"));
1513 // Trigger in page navigation.
1514 std::string in_page_navigate = "location.hash = '#blah';";
1515 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), in_page_navigate));
1517 // Click on the username field to display the popup.
1518 int top;
1519 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1520 RenderViewHost(),
1521 "window.domAutomationController.send(usernameRect.top);",
1522 &top));
1523 int left;
1524 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1525 RenderViewHost(),
1526 "window.domAutomationController.send(usernameRect.left);",
1527 &left));
1529 content::SimulateMouseClickAt(
1530 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(left + 1,
1531 top + 1));
1532 // Make sure the popup would be shown.
1533 observing_autofill_client.Wait();
1536 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1537 ChangePwdFormBubbleShown) {
1538 NavigateToFile("/password/password_form.html");
1540 NavigationObserver observer(WebContents());
1541 scoped_ptr<PromptObserver> prompt_observer(
1542 PromptObserver::Create(WebContents()));
1543 std::string fill_and_submit =
1544 "document.getElementById('chg_username_field').value = 'temp';"
1545 "document.getElementById('chg_password_field').value = 'random';"
1546 "document.getElementById('chg_new_password_1').value = 'random1';"
1547 "document.getElementById('chg_new_password_2').value = 'random1';"
1548 "document.getElementById('chg_submit_button').click()";
1549 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1550 observer.Wait();
1551 // TODO(dvadym): Turn on this test when Change password UI will be implemented
1552 // for Mac. http://crbug.com/359315
1553 #if defined(OS_MACOSX)
1554 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1555 #else
1556 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1557 #endif
1560 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1561 ChangePwdFormPushStateBubbleShown) {
1562 NavigateToFile("/password/password_push_state.html");
1564 NavigationObserver observer(WebContents());
1565 observer.set_quit_on_entry_committed(true);
1566 scoped_ptr<PromptObserver> prompt_observer(
1567 PromptObserver::Create(WebContents()));
1568 std::string fill_and_submit =
1569 "document.getElementById('chg_username_field').value = 'temp';"
1570 "document.getElementById('chg_password_field').value = 'random';"
1571 "document.getElementById('chg_new_password_1').value = 'random1';"
1572 "document.getElementById('chg_new_password_2').value = 'random1';"
1573 "document.getElementById('chg_submit_button').click()";
1574 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1575 observer.Wait();
1576 // TODO(dvadym): Turn on this test when Change password UI will be implemented
1577 // for Mac. http://crbug.com/359315
1578 #if defined(OS_MACOSX)
1579 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1580 #else
1581 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1582 #endif
1585 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoPromptOnBack) {
1586 // Go to a successful landing page through submitting first, so that it is
1587 // reachable through going back, and the remembered page transition is form
1588 // submit. There is no need to submit non-empty strings.
1589 NavigateToFile("/password/password_form.html");
1591 NavigationObserver dummy_submit_observer(WebContents());
1592 std::string just_submit =
1593 "document.getElementById('input_submit_button').click()";
1594 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), just_submit));
1595 dummy_submit_observer.Wait();
1597 // Now go to a page with a form again, fill the form, and go back instead of
1598 // submitting it.
1599 NavigateToFile("/password/dummy_submit.html");
1601 NavigationObserver observer(WebContents());
1602 scoped_ptr<PromptObserver> prompt_observer(
1603 PromptObserver::Create(WebContents()));
1604 // The (dummy) submit is necessary to provisionally save the typed password. A
1605 // user typing in the password field would not need to submit to provisionally
1606 // save it, but the script cannot trigger that just by assigning to the
1607 // field's value.
1608 std::string fill_and_back =
1609 "document.getElementById('password_field').value = 'random';"
1610 "document.getElementById('input_submit_button').click();"
1611 "window.history.back();";
1612 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_back));
1613 observer.Wait();
1614 EXPECT_FALSE(prompt_observer->IsShowingPrompt());
1617 // Regression test for http://crbug.com/452306
1618 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1619 ChangingTextToPasswordFieldOnSignupForm) {
1620 NavigateToFile("/password/signup_form.html");
1622 // In this case, pretend that username_field is actually a password field
1623 // that starts as a text field to simulate placeholder.
1624 NavigationObserver observer(WebContents());
1625 scoped_ptr<PromptObserver> prompt_observer(
1626 PromptObserver::Create(WebContents()));
1627 std::string change_and_submit =
1628 "document.getElementById('other_info').value = 'username';"
1629 "document.getElementById('username_field').type = 'password';"
1630 "document.getElementById('username_field').value = 'mypass';"
1631 "document.getElementById('password_field').value = 'mypass';"
1632 "document.getElementById('testform').submit();";
1633 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), change_and_submit));
1634 observer.Wait();
1635 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1638 // Regression test for http://crbug.com/451631
1639 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1640 SavingOnManyPasswordFieldsTest) {
1641 // Simulate Macy's registration page, which contains the normal 2 password
1642 // fields for confirming the new password plus 2 more fields for security
1643 // questions and credit card. Make sure that saving works correctly for such
1644 // sites.
1645 NavigateToFile("/password/many_password_signup_form.html");
1647 NavigationObserver observer(WebContents());
1648 scoped_ptr<PromptObserver> prompt_observer(
1649 PromptObserver::Create(WebContents()));
1650 std::string fill_and_submit =
1651 "document.getElementById('username_field').value = 'username';"
1652 "document.getElementById('password_field').value = 'mypass';"
1653 "document.getElementById('confirm_field').value = 'mypass';"
1654 "document.getElementById('security_answer').value = 'hometown';"
1655 "document.getElementById('SSN').value = '1234';"
1656 "document.getElementById('testform').submit();";
1657 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1658 observer.Wait();
1659 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1662 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1663 SaveWhenIFrameDestroyedOnFormSubmit) {
1664 NavigateToFile("/password/frame_detached_on_submit.html");
1666 // Need to pay attention for a message that XHR has finished since there
1667 // is no navigation to wait for.
1668 content::DOMMessageQueue message_queue;
1670 scoped_ptr<PromptObserver> prompt_observer(
1671 PromptObserver::Create(WebContents()));
1672 std::string fill_and_submit =
1673 "var iframe = document.getElementById('login_iframe');"
1674 "var frame_doc = iframe.contentDocument;"
1675 "frame_doc.getElementById('username_field').value = 'temp';"
1676 "frame_doc.getElementById('password_field').value = 'random';"
1677 "frame_doc.getElementById('submit_button').click();";
1679 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1680 std::string message;
1681 while (message_queue.WaitForMessage(&message)) {
1682 if (message == "\"SUBMISSION_FINISHED\"")
1683 break;
1686 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1689 // Tests that if a site embeds the login and signup forms into one <form>, the
1690 // login form still gets autofilled.
1691 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1692 AutofillSuggetionsForLoginSignupForm) {
1693 std::string submit =
1694 "document.getElementById('username').value = 'myusername';"
1695 "document.getElementById('password').value = 'mypassword';"
1696 "document.getElementById('submit').click();";
1697 VerifyPasswordIsSavedAndFilled("/password/login_signup_form.html",
1698 submit, "password", "mypassword");
1701 // Check that we can fill in cases where <base href> is set and the action of
1702 // the form is not set. Regression test for https://crbug.com/360230.
1703 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1704 BaseTagWithNoActionTest) {
1705 std::string submit =
1706 "document.getElementById('username_field').value = 'myusername';"
1707 "document.getElementById('password_field').value = 'mypassword';"
1708 "document.getElementById('submit_button').click();";
1709 VerifyPasswordIsSavedAndFilled("/password/password_xhr_submit.html",
1710 submit, "password_field", "mypassword");
1713 // Check that a password form in an iframe of different origin will not be
1714 // filled in until a user interact with the form.
1715 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1716 CrossSiteIframeNotFillTest) {
1717 // Setup the mock host resolver
1718 host_resolver()->AddRule("*", "127.0.0.1");
1720 // Here we need to dynamically create the iframe because the port
1721 // embedded_test_server ran on was dynamically allocated, so the iframe's src
1722 // attribute can only be determined at run time.
1723 NavigateToFile("/password/password_form_in_crosssite_iframe.html");
1724 NavigationObserver ifrm_observer(WebContents());
1725 ifrm_observer.SetPathToWaitFor("/password/crossite_iframe_content.html");
1726 std::string create_iframe = base::StringPrintf(
1727 "create_iframe("
1728 "'http://randomsite.net:%d/password/crossite_iframe_content.html');",
1729 embedded_test_server()->port());
1730 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_iframe));
1731 ifrm_observer.Wait();
1733 // Store a password for autofill later
1734 NavigationObserver init_observer(WebContents());
1735 init_observer.SetPathToWaitFor("/password/done.html");
1736 scoped_ptr<PromptObserver> prompt_observer(
1737 PromptObserver::Create(WebContents()));
1738 std::string init_form = "sendMessage('fill_and_submit');";
1739 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), init_form));
1740 init_observer.Wait();
1741 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1742 prompt_observer->Accept();
1744 // Visit the form again
1745 NavigationObserver reload_observer(WebContents());
1746 NavigateToFile("/password/password_form_in_crosssite_iframe.html");
1747 reload_observer.Wait();
1749 NavigationObserver ifrm_observer_2(WebContents());
1750 ifrm_observer_2.SetPathToWaitFor("/password/crossite_iframe_content.html");
1751 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_iframe));
1752 ifrm_observer_2.Wait();
1754 // Verify username is not autofilled
1755 std::string empty_username;
1756 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1757 RenderViewHost(),
1758 "sendMessage('get_username');",
1759 &empty_username));
1760 ASSERT_EQ("", empty_username);
1761 // Verify password is not autofilled
1762 std::string empty_password;
1763 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1764 RenderViewHost(),
1765 "sendMessage('get_password');",
1766 &empty_password));
1767 ASSERT_EQ("", empty_password);
1769 // Simulate the user interaction in the iframe and verify autofill is not
1770 // triggered. Note this check is only best-effort because we don't know how
1771 // long to wait before we are certain that no autofill will be triggered.
1772 // Theoretically unexpected autofill can happen after this check.
1773 ASSERT_TRUE(content::ExecuteScript(
1774 RenderViewHost(),
1775 "var iframeRect = document.getElementById("
1776 "'iframe').getBoundingClientRect();"));
1777 int top;
1778 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1779 RenderViewHost(),
1780 "window.domAutomationController.send(iframeRect.top);",
1781 &top));
1782 int left;
1783 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1784 RenderViewHost(),
1785 "window.domAutomationController.send(iframeRect.left);",
1786 &left));
1788 content::SimulateMouseClickAt(
1789 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(left + 1,
1790 top + 1));
1791 // Verify username is not autofilled
1792 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1793 RenderViewHost(),
1794 "sendMessage('get_username');",
1795 &empty_username));
1796 ASSERT_EQ("", empty_username);
1797 // Verify password is not autofilled
1798 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1799 RenderViewHost(),
1800 "sendMessage('get_password');",
1801 &empty_password));
1802 ASSERT_EQ("", empty_password);
1805 // Check that a password form in an iframe of same origin will not be
1806 // filled in until user interact with the iframe.
1807 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1808 SameOriginIframeAutoFillTest) {
1809 // Visit the sign-up form to store a password for autofill later
1810 NavigateToFile("/password/password_form_in_same_origin_iframe.html");
1811 NavigationObserver observer(WebContents());
1812 observer.SetPathToWaitFor("/password/done.html");
1813 scoped_ptr<PromptObserver> prompt_observer(
1814 PromptObserver::Create(WebContents()));
1816 std::string submit =
1817 "var ifrmDoc = document.getElementById('iframe').contentDocument;"
1818 "ifrmDoc.getElementById('username_field').value = 'temp';"
1819 "ifrmDoc.getElementById('password_field').value = 'pa55w0rd';"
1820 "ifrmDoc.getElementById('input_submit_button').click();";
1821 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), submit));
1822 observer.Wait();
1823 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1824 prompt_observer->Accept();
1826 // Visit the form again
1827 NavigationObserver reload_observer(WebContents());
1828 NavigateToFile("/password/password_form_in_same_origin_iframe.html");
1829 reload_observer.Wait();
1831 // Verify username is autofilled
1832 CheckElementValue("iframe", "username_field", "temp");
1834 // Verify password is not autofilled
1835 CheckElementValue("iframe", "password_field", "");
1837 // Simulate the user interaction in the iframe which should trigger autofill.
1838 ASSERT_TRUE(content::ExecuteScript(
1839 RenderViewHost(),
1840 "var iframeRect = document.getElementById("
1841 "'iframe').getBoundingClientRect();"));
1842 int top;
1843 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1844 RenderViewHost(),
1845 "window.domAutomationController.send(iframeRect.top);",
1846 &top));
1847 int left;
1848 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1849 RenderViewHost(),
1850 "window.domAutomationController.send(iframeRect.left);",
1851 &left));
1853 content::SimulateMouseClickAt(
1854 WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(left + 1,
1855 top + 1));
1856 // Verify password has been autofilled
1857 WaitForElementValue("iframe", "password_field", "pa55w0rd");
1859 // Verify username has been autofilled
1860 CheckElementValue("iframe", "username_field", "temp");
1863 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, NoFormElementTest) {
1864 std::string submit =
1865 "document.getElementById('username_field').value = 'myusername';"
1866 "document.getElementById('password_field').value = 'mypassword';"
1867 "send_xhr();";
1868 VerifyPasswordIsSavedAndFilled("/password/no_form_element.html",
1869 submit,
1870 "password_field",
1871 "mypassword");
1874 // The password manager driver will kill processes when they try to access
1875 // passwords of sites other than the site the process is dedicated to, under
1876 // site isolation.
1877 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1878 CrossSitePasswordEnforcement) {
1879 // The code under test is only active under site isolation.
1880 if (!content::AreAllSitesIsolatedForTesting()) {
1881 return;
1884 // Setup the mock host resolver
1885 host_resolver()->AddRule("*", "127.0.0.1");
1887 // Navigate the main frame.
1888 GURL main_frame_url = embedded_test_server()->GetURL(
1889 "/password/password_form_in_crosssite_iframe.html");
1890 NavigationObserver observer(WebContents());
1891 ui_test_utils::NavigateToURL(browser(), main_frame_url);
1892 observer.Wait();
1894 // Create an iframe and navigate cross-site.
1895 NavigationObserver iframe_observer(WebContents());
1896 iframe_observer.SetPathToWaitFor("/password/crossite_iframe_content.html");
1897 GURL iframe_url = embedded_test_server()->GetURL(
1898 "foo.com", "/password/crossite_iframe_content.html");
1899 std::string create_iframe =
1900 base::StringPrintf("create_iframe('%s');", iframe_url.spec().c_str());
1901 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), create_iframe));
1902 iframe_observer.Wait();
1904 // The iframe should get its own process.
1905 content::RenderFrameHost* main_frame = WebContents()->GetMainFrame();
1906 content::RenderFrameHost* iframe = iframe_observer.render_frame_host();
1907 content::SiteInstance* main_site_instance = main_frame->GetSiteInstance();
1908 content::SiteInstance* iframe_site_instance = iframe->GetSiteInstance();
1909 EXPECT_NE(main_site_instance, iframe_site_instance);
1910 EXPECT_NE(main_frame->GetProcess(), iframe->GetProcess());
1912 // Try to get cross-site passwords from the subframe's process and wait for it
1913 // to be killed.
1914 std::vector<autofill::PasswordForm> password_forms;
1915 password_forms.push_back(autofill::PasswordForm());
1916 password_forms.back().origin = main_frame_url;
1917 AutofillHostMsg_PasswordFormsParsed illegal_forms_parsed(
1918 iframe->GetRoutingID(), password_forms);
1920 content::RenderProcessHostWatcher iframe_killed(
1921 iframe->GetProcess(),
1922 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
1924 IPC::IpcSecurityTestUtil::PwnMessageReceived(
1925 iframe->GetProcess()->GetChannel(), illegal_forms_parsed);
1927 iframe_killed.Wait();
1930 // TODO(dvadym): Turn on this test when Change password UI will be implemented
1931 // for Mac. http://crbug.com/359315
1932 #if !defined(OS_MACOSX)
1933 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1934 ChangePwdNoAccountStored) {
1935 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
1936 NavigateToFile("/password/password_form.html");
1938 // Fill a form and submit through a <input type="submit"> button.
1939 NavigationObserver observer(WebContents());
1940 scoped_ptr<PromptObserver> prompt_observer(
1941 PromptObserver::Create(WebContents()));
1943 std::string fill_and_submit =
1944 "document.getElementById('chg_password_wo_username_field').value = "
1945 "'old_pw';"
1946 "document.getElementById('chg_new_password_wo_username_1').value = "
1947 "'new_pw';"
1948 "document.getElementById('chg_new_password_wo_username_2').value = "
1949 "'new_pw';"
1950 "document.getElementById('chg_submit_wo_username_button').click()";
1951 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
1952 observer.Wait();
1953 // No credentials stored before, so save bubble is shown.
1954 EXPECT_TRUE(prompt_observer->IsShowingPrompt());
1955 prompt_observer->Accept();
1956 // Check that credentials are stored.
1957 scoped_refptr<password_manager::TestPasswordStore> password_store =
1958 static_cast<password_manager::TestPasswordStore*>(
1959 PasswordStoreFactory::GetForProfile(
1960 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
1961 .get());
1962 // Spin the message loop to make sure the password store had a chance to save
1963 // the password.
1964 base::RunLoop run_loop;
1965 run_loop.RunUntilIdle();
1966 EXPECT_FALSE(password_store->IsEmpty());
1967 CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16(""),
1968 base::ASCIIToUTF16("new_pw"));
1970 #endif
1972 // TODO(dvadym): Turn on this test when Change password UI will be implemented
1973 // for Mac. http://crbug.com/359315
1974 #if !defined(OS_MACOSX)
1975 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
1976 ChangePwd1AccountStored) {
1977 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
1978 // At first let us save credentials to the PasswordManager.
1979 scoped_refptr<password_manager::TestPasswordStore> password_store =
1980 static_cast<password_manager::TestPasswordStore*>(
1981 PasswordStoreFactory::GetForProfile(
1982 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
1983 .get());
1984 autofill::PasswordForm signin_form;
1985 signin_form.signon_realm = embedded_test_server()->base_url().spec();
1986 signin_form.password_value = base::ASCIIToUTF16("pw");
1987 signin_form.username_value = base::ASCIIToUTF16("temp");
1988 password_store->AddLogin(signin_form);
1990 // Check that password update bubble is shown.
1991 NavigateToFile("/password/password_form.html");
1992 NavigationObserver observer(WebContents());
1993 scoped_ptr<PromptObserver> prompt_observer(
1994 PromptObserver::Create(WebContents()));
1995 std::string fill_and_submit_change_password =
1996 "document.getElementById('chg_password_wo_username_field').value = "
1997 "'random';"
1998 "document.getElementById('chg_new_password_wo_username_1').value = "
1999 "'new_pw';"
2000 "document.getElementById('chg_new_password_wo_username_2').value = "
2001 "'new_pw';"
2002 "document.getElementById('chg_submit_wo_username_button').click()";
2003 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(),
2004 fill_and_submit_change_password));
2005 observer.Wait();
2006 EXPECT_TRUE(prompt_observer->IsShowingUpdatePrompt());
2008 const autofill::PasswordForm stored_form =
2009 password_store->stored_passwords().begin()->second[0];
2010 prompt_observer->AcceptUpdatePrompt(stored_form);
2011 // Spin the message loop to make sure the password store had a chance to
2012 // update the password.
2013 base::RunLoop run_loop;
2014 run_loop.RunUntilIdle();
2015 CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16("temp"),
2016 base::ASCIIToUTF16("new_pw"));
2018 #endif
2020 // TODO(dvadym): Turn on this test when Change password UI will be implemented
2021 // for Mac. http://crbug.com/359315
2022 #if !defined(OS_MACOSX)
2023 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
2024 PasswordOverridenUpdateBubbleShown) {
2025 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
2026 // At first let us save credentials to the PasswordManager.
2027 scoped_refptr<password_manager::TestPasswordStore> password_store =
2028 static_cast<password_manager::TestPasswordStore*>(
2029 PasswordStoreFactory::GetForProfile(
2030 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
2031 .get());
2032 autofill::PasswordForm signin_form;
2033 signin_form.signon_realm = embedded_test_server()->base_url().spec();
2034 signin_form.username_value = base::ASCIIToUTF16("temp");
2035 signin_form.password_value = base::ASCIIToUTF16("pw");
2036 password_store->AddLogin(signin_form);
2038 // Check that password update bubble is shown.
2039 NavigateToFile("/password/password_form.html");
2040 NavigationObserver observer(WebContents());
2041 scoped_ptr<PromptObserver> prompt_observer(
2042 PromptObserver::Create(WebContents()));
2043 std::string fill_and_submit =
2044 "document.getElementById('username_field').value = 'temp';"
2045 "document.getElementById('password_field').value = 'new_pw';"
2046 "document.getElementById('input_submit_button').click()";
2047 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
2048 observer.Wait();
2049 // The stored password "pw" was overriden with "new_pw", so update prompt is
2050 // expected.
2051 EXPECT_TRUE(prompt_observer->IsShowingUpdatePrompt());
2053 const autofill::PasswordForm stored_form =
2054 password_store->stored_passwords().begin()->second[0];
2055 prompt_observer->AcceptUpdatePrompt(stored_form);
2056 // Spin the message loop to make sure the password store had a chance to
2057 // update the password.
2058 base::RunLoop run_loop;
2059 run_loop.RunUntilIdle();
2060 CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16("temp"),
2061 base::ASCIIToUTF16("new_pw"));
2063 #endif
2065 // TODO(dvadym): Turn on this test when Change password UI will be implemented
2066 // for Mac. http://crbug.com/359315
2067 #if !defined(OS_MACOSX)
2068 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
2069 PasswordNotOverridenUpdateBubbleNotShown) {
2070 ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
2071 // At first let us save credentials to the PasswordManager.
2072 scoped_refptr<password_manager::TestPasswordStore> password_store =
2073 static_cast<password_manager::TestPasswordStore*>(
2074 PasswordStoreFactory::GetForProfile(
2075 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
2076 .get());
2077 autofill::PasswordForm signin_form;
2078 signin_form.signon_realm = embedded_test_server()->base_url().spec();
2079 signin_form.username_value = base::ASCIIToUTF16("temp");
2080 signin_form.password_value = base::ASCIIToUTF16("pw");
2081 password_store->AddLogin(signin_form);
2083 // Check that password update bubble is shown.
2084 NavigateToFile("/password/password_form.html");
2085 NavigationObserver observer(WebContents());
2086 scoped_ptr<PromptObserver> prompt_observer(
2087 PromptObserver::Create(WebContents()));
2088 std::string fill_and_submit =
2089 "document.getElementById('username_field').value = 'temp';"
2090 "document.getElementById('password_field').value = 'pw';"
2091 "document.getElementById('input_submit_button').click()";
2092 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit));
2093 observer.Wait();
2094 // The stored password "pw" was not overriden, so update prompt is not
2095 // expected.
2096 EXPECT_FALSE(prompt_observer->IsShowingUpdatePrompt());
2097 CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16("temp"),
2098 base::ASCIIToUTF16("pw"));
2100 #endif
2102 } // namespace password_manager