Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/macros.h" | 5 #include "base/macros.h" |
| 6 #include "base/run_loop.h" | |
| 6 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "base/strings/stringprintf.h" | |
| 7 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/password_manager/chrome_password_manager_client.h" | |
| 8 #include "chrome/browser/password_manager/password_manager_test_base.h" | 11 #include "chrome/browser/password_manager/password_manager_test_base.h" |
| 9 #include "chrome/browser/password_manager/password_store_factory.h" | 12 #include "chrome/browser/password_manager/password_store_factory.h" |
| 10 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/browser/profiles/profile_io_data.h" | 14 #include "chrome/browser/profiles/profile_io_data.h" |
| 12 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/passwords/passwords_model_delegate.h" | 16 #include "chrome/browser/ui/passwords/passwords_model_delegate.h" |
| 17 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
| 14 #include "chrome/test/base/ui_test_utils.h" | 18 #include "chrome/test/base/ui_test_utils.h" |
| 15 #include "components/password_manager/core/browser/password_bubble_experiment.h" | 19 #include "components/password_manager/core/browser/password_bubble_experiment.h" |
| 16 #include "components/password_manager/core/browser/test_password_store.h" | 20 #include "components/password_manager/core/browser/test_password_store.h" |
| 21 #include "content/public/browser/web_contents.h" | |
| 22 #include "content/public/browser/web_contents_observer.h" | |
| 17 #include "content/public/test/browser_test.h" | 23 #include "content/public/test/browser_test.h" |
| 18 #include "content/public/test/browser_test_utils.h" | 24 #include "content/public/test/browser_test_utils.h" |
| 19 #include "net/dns/mock_host_resolver.h" | 25 #include "net/dns/mock_host_resolver.h" |
| 20 | 26 |
| 21 namespace { | 27 namespace { |
| 22 | 28 |
| 29 // This class implements waiting for RenderFrameHost destruction. It relies on | |
| 30 // the fact that RenderFrameDeleted event is fired when RenderFrameHost is | |
| 31 // destroyed. | |
|
vasilii
2017/06/29 11:59:59
Is the second sentence trying to say more than "Re
engedy
2017/06/30 19:41:55
Yes, there is a subtle difference between the `Del
| |
| 32 class RenderFrameHostDestructionObserver : public content::WebContentsObserver { | |
| 33 public: | |
| 34 explicit RenderFrameHostDestructionObserver(content::RenderFrameHost* rfh) | |
| 35 : WebContentsObserver(content::WebContents::FromRenderFrameHost(rfh)), | |
| 36 render_frame_host_(rfh) {} | |
| 37 ~RenderFrameHostDestructionObserver() override {} | |
| 38 | |
| 39 void WaitForDestruction() { | |
| 40 if (destroyed_) | |
| 41 return; | |
|
vasilii
2017/06/29 11:59:59
Note that if destroyed_ is true then run_loop_.Run
engedy
2017/06/30 19:41:55
N/A, removed this class.
| |
| 42 run_loop_.Run(); | |
| 43 } | |
| 44 | |
| 45 // WebContentsObserver: | |
| 46 void RenderFrameDeleted(content::RenderFrameHost* rfh) override { | |
| 47 if (rfh == render_frame_host_) { | |
| 48 ASSERT_FALSE(destroyed_); | |
| 49 destroyed_ = true; | |
| 50 run_loop_.Quit(); | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 private: | |
| 55 base::RunLoop run_loop_; | |
| 56 content::RenderFrameHost* render_frame_host_; | |
| 57 | |
| 58 bool destroyed_ = false; | |
| 59 | |
| 60 DISALLOW_COPY_AND_ASSIGN(RenderFrameHostDestructionObserver); | |
| 61 }; | |
| 62 | |
| 23 class CredentialManagerBrowserTest : public PasswordManagerBrowserTestBase { | 63 class CredentialManagerBrowserTest : public PasswordManagerBrowserTestBase { |
| 24 public: | 64 public: |
| 25 CredentialManagerBrowserTest() = default; | 65 CredentialManagerBrowserTest() = default; |
| 26 | 66 |
| 27 void SetUpOnMainThread() override { | 67 void SetUpOnMainThread() override { |
| 28 PasswordManagerBrowserTestBase::SetUpOnMainThread(); | 68 PasswordManagerBrowserTestBase::SetUpOnMainThread(); |
| 29 // Redirect all requests to localhost. | 69 // Redirect all requests to localhost. |
| 30 host_resolver()->AddRule("*", "127.0.0.1"); | 70 host_resolver()->AddRule("*", "127.0.0.1"); |
| 31 } | 71 } |
| 32 | 72 |
| 33 bool IsShowingAccountChooser() { | 73 bool IsShowingAccountChooser() { |
| 34 return PasswordsModelDelegateFromWebContents(WebContents())-> | 74 return PasswordsModelDelegateFromWebContents(WebContents())-> |
| 35 GetState() == password_manager::ui::CREDENTIAL_REQUEST_STATE; | 75 GetState() == password_manager::ui::CREDENTIAL_REQUEST_STATE; |
| 36 } | 76 } |
| 37 | 77 |
| 38 // Similarly to PasswordManagerBrowserTestBase::NavigateToFile this is a | 78 // Similarly to PasswordManagerBrowserTestBase::NavigateToFile this is a |
| 39 // wrapper around ui_test_utils::NavigateURL that waits until DidFinishLoad() | 79 // wrapper around ui_test_utils::NavigateURL that waits until DidFinishLoad() |
| 40 // fires. Different to NavigateToFile this method allows passing a test_server | 80 // fires. Different to NavigateToFile this method allows passing a test_server |
| 41 // and modifications to the hostname. | 81 // and modifications to the hostname. |
| 42 void NavigateToURL(const net::EmbeddedTestServer& test_server, | 82 void NavigateToURL(const net::EmbeddedTestServer& test_server, |
| 43 const std::string& hostname, | 83 const std::string& hostname, |
| 44 const std::string& relative_url) { | 84 const std::string& relative_url) { |
| 45 NavigationObserver observer(WebContents()); | 85 NavigationObserver observer(WebContents()); |
| 46 GURL url = test_server.GetURL(hostname, relative_url); | 86 GURL url = test_server.GetURL(hostname, relative_url); |
| 47 ui_test_utils::NavigateToURL(browser(), url); | 87 ui_test_utils::NavigateToURL(browser(), url); |
| 48 observer.Wait(); | 88 observer.Wait(); |
| 49 } | 89 } |
| 50 | 90 |
| 91 // Triggers a call to `navigator.credentials.get` to retrieve passwords, waits | |
| 92 // for success, and ASSERTs that |expect_has_results| is satisfied. | |
| 93 void TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 94 content::WebContents* web_contents, | |
| 95 bool expect_has_results) { | |
| 96 bool result = false; | |
| 97 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
| 98 web_contents, | |
| 99 "navigator.credentials.get({password: true}).then(c => {" | |
| 100 " window.domAutomationController.send(!!c);" | |
| 101 "});", | |
| 102 &result)); | |
| 103 ASSERT_EQ(expect_has_results, result); | |
| 104 } | |
| 105 | |
| 106 // Schedules a call to be made to navigator.credentials.store() in the | |
| 107 // `unload` handler to save a credential with |username| and |password|. | |
| 108 void ScheduleNavigatorStoreCredentialAtUnload( | |
| 109 content::WebContents* web_contents, | |
| 110 const char* username, | |
| 111 const char* password) { | |
| 112 ASSERT_TRUE(content::ExecuteScript( | |
| 113 web_contents, | |
| 114 base::StringPrintf( | |
| 115 "window.addEventListener(\"unload\", () => {" | |
| 116 " var c = new PasswordCredential({ id: '%s', password: '%s' });" | |
| 117 " navigator.credentials.store(c);" | |
| 118 "});", | |
| 119 username, password))); | |
| 120 } | |
| 121 | |
| 122 content::WebContents* active_web_contents() { | |
| 123 return browser()->tab_strip_model()->GetActiveWebContents(); | |
| 124 } | |
| 125 | |
| 51 private: | 126 private: |
| 52 DISALLOW_COPY_AND_ASSIGN(CredentialManagerBrowserTest); | 127 DISALLOW_COPY_AND_ASSIGN(CredentialManagerBrowserTest); |
| 53 }; | 128 }; |
| 54 | 129 |
| 55 // Tests. | 130 // Tests. |
| 56 | 131 |
| 57 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, | 132 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, |
| 58 AccountChooserWithOldCredentialAndNavigation) { | 133 AccountChooserWithOldCredentialAndNavigation) { |
| 59 // Save credentials with 'skip_zero_click'. | 134 // Save credentials with 'skip_zero_click'. |
| 60 scoped_refptr<password_manager::TestPasswordStore> password_store = | 135 scoped_refptr<password_manager::TestPasswordStore> password_store = |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 NavigationObserver observer(WebContents()); | 313 NavigationObserver observer(WebContents()); |
| 239 observer.SetPathToWaitFor("/password/done.html"); | 314 observer.SetPathToWaitFor("/password/done.html"); |
| 240 observer.Wait(); | 315 observer.Wait(); |
| 241 | 316 |
| 242 BubbleObserver prompt_observer(WebContents()); | 317 BubbleObserver prompt_observer(WebContents()); |
| 243 // The autofill password manager shouldn't react to the successful login | 318 // The autofill password manager shouldn't react to the successful login |
| 244 // because it was suppressed when the site got the credential back. | 319 // because it was suppressed when the site got the credential back. |
| 245 EXPECT_FALSE(prompt_observer.IsShowingSavePrompt()); | 320 EXPECT_FALSE(prompt_observer.IsShowingSavePrompt()); |
| 246 } | 321 } |
| 247 | 322 |
| 323 // Regression test for https://crbug.com/736357. | |
| 324 IN_PROC_BROWSER_TEST_F( | |
| 325 CredentialManagerBrowserTest, | |
| 326 StoreInUnloadHandler_ServicedUsingPriorURLForSameSiteNavigation) { | |
| 327 // Use URLs that differ on subdomains so we can tell which one was used for | |
| 328 // saving, but they still belong to the same SiteInstance, so they will be | |
| 329 // renderered in the same process. | |
| 330 const GURL a_url1 = https_test_server().GetURL("foo.a.com", "/title1.html"); | |
| 331 const GURL a_url2 = https_test_server().GetURL("bar.a.com", "/title2.html"); | |
| 332 | |
| 333 for (const auto preestablish_mojo_pipe : {false, true}) { | |
|
vasilii
2017/06/29 11:59:59
I'd prefer to split this test into two. The body c
vasilii
2017/06/29 12:00:00
const bool
engedy
2017/06/30 19:41:55
Done.
engedy
2017/06/30 19:41:55
Ack. Done this one, and also the one below.
| |
| 334 SCOPED_TRACE(::testing::Message() | |
| 335 << "Pre-establish Mojo pipe ahead of time: " | |
| 336 << preestablish_mojo_pipe); | |
| 337 | |
| 338 // Open a new WebContents, navigate to a mostly empty page. | |
| 339 NavigateToURLWithDisposition( | |
| 340 browser(), a_url1, WindowOpenDisposition::NEW_FOREGROUND_TAB, | |
| 341 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
| 342 | |
| 343 ChromePasswordManagerClient* client = | |
| 344 ChromePasswordManagerClient::FromWebContents(active_web_contents()); | |
| 345 | |
| 346 // Optionally set up a Mojo connection to the CredentialManagerImpl ahead of | |
| 347 // time, instead of letting it be established on-demand when the call to | |
| 348 // store() triggered from the unload handler. | |
| 349 if (preestablish_mojo_pipe) { | |
| 350 EXPECT_FALSE(client->has_binding_for_credential_manager()); | |
| 351 ASSERT_NO_FATAL_FAILURE( | |
| 352 TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 353 active_web_contents(), false)); | |
| 354 EXPECT_TRUE(client->has_binding_for_credential_manager()); | |
| 355 } | |
| 356 | |
| 357 // Schedule storing a credential on the `unload` event. | |
| 358 ASSERT_NO_FATAL_FAILURE(ScheduleNavigatorStoreCredentialAtUnload( | |
| 359 active_web_contents(), "user", "hunter2")); | |
| 360 | |
| 361 // Trigger a same-site navigation that is carried out in the same renderer. | |
| 362 content::RenderFrameHost* old_rfh = active_web_contents()->GetMainFrame(); | |
| 363 ui_test_utils::NavigateToURL(browser(), a_url2); | |
| 364 base::RunLoop().RunUntilIdle(); | |
|
vasilii
2017/06/29 11:59:59
I'm not a big fan of RunUntilIdle() in the browser
engedy
2017/06/30 19:41:55
Done.
| |
| 365 ASSERT_EQ(old_rfh, active_web_contents()->GetMainFrame()); | |
| 366 | |
| 367 // Ensure that the old document no longer has a Mojo connection to the | |
| 368 // CredentialManagerImpl, nor can it get one later. | |
| 369 // | |
| 370 // Because the InterfaceRegistry through which the interface to the | |
| 371 // CredentialManagerImpl is retrieved is synchronized to FrameHost | |
|
vasilii
2017/06/29 11:59:59
Is this request itself coming from IPC?
engedy
2017/06/30 19:41:54
As discussed offline, made this an associated inte
| |
| 372 // messages, there cannot be InterfaceRequest messages in flight. | |
| 373 // | |
| 374 // Furthermore, FrameLoader::PrepareForCommit had already shut down the old | |
| 375 // Document before the provisional load could be commited in the renderer, | |
| 376 // so no new InterfaceRequests can be issued either. | |
| 377 // | |
| 378 // Hence it is sufficient to check that the Mojo connection is closed now. | |
| 379 EXPECT_FALSE(client->has_binding_for_credential_manager()); | |
|
vasilii
2017/06/29 11:59:59
Is it the check that would fail before the CL?
engedy
2017/06/30 19:41:55
Among others, yes.
| |
| 380 | |
| 381 // Ensure that the navigator.credentials.store() call was either never | |
| 382 // serviced, or was serviced in the context of the old URL, |a_url|. | |
| 383 // | |
| 384 // Both are possible, as CredentialManager Mojo messages on an pre-existing | |
| 385 // connection are no longer synchronized to FrameHost messages. Therefore, | |
| 386 // servicing the store() called from the `unload` handler, triggered from | |
| 387 // FrameLoader::PrepareForCommit, is at race with DidFinishNavigation, which | |
| 388 // is triggered by FrameHostMsg DidCommitProvisionalLoad. | |
| 389 if (client->was_store_ever_called()) { | |
| 390 BubbleObserver prompt_observer(active_web_contents()); | |
| 391 prompt_observer.WaitForSavePrompt(); | |
|
vasilii
2017/06/29 11:59:59
You may really crash here.
WaitForSavePrompt() ca
engedy
2017/06/30 19:41:54
Done. (Using WebContents() now.)
| |
| 392 ASSERT_TRUE(prompt_observer.IsShowingSavePrompt()); | |
| 393 prompt_observer.AcceptSavePrompt(); | |
| 394 | |
| 395 WaitForPasswordStore(); | |
| 396 | |
| 397 password_manager::TestPasswordStore* test_password_store = | |
| 398 static_cast<password_manager::TestPasswordStore*>( | |
| 399 PasswordStoreFactory::GetForProfile( | |
| 400 browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS) | |
| 401 .get()); | |
| 402 | |
| 403 ASSERT_EQ(1u, test_password_store->stored_passwords().size()); | |
| 404 autofill::PasswordForm signin_form = | |
| 405 test_password_store->stored_passwords().begin()->second[0]; | |
| 406 EXPECT_EQ(base::ASCIIToUTF16("user"), signin_form.username_value); | |
| 407 EXPECT_EQ(base::ASCIIToUTF16("hunter2"), signin_form.password_value); | |
| 408 EXPECT_EQ(a_url1.GetOrigin(), signin_form.origin); | |
| 409 test_password_store->Clear(); | |
| 410 } | |
| 411 } | |
| 412 } | |
| 413 | |
| 414 // Regression test for https://crbug.com/736357. | |
| 415 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, | |
| 416 StoreInUnloadHandler_IgnoredOnCrossSiteNavigation) { | |
| 417 const GURL a_url = https_test_server().GetURL("a.com", "/title1.html"); | |
| 418 const GURL b_url = https_test_server().GetURL("b.com", "/title2.html"); | |
| 419 | |
| 420 for (const auto preestablish_mojo_pipe : {false, true}) { | |
| 421 SCOPED_TRACE(::testing::Message() | |
| 422 << "Pre-establish Mojo pipe ahead of time: " | |
| 423 << preestablish_mojo_pipe); | |
| 424 | |
| 425 // Open a new WebContents, navigate to a mostly empty page. | |
| 426 NavigateToURLWithDisposition( | |
| 427 browser(), a_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, | |
| 428 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
| 429 | |
| 430 ChromePasswordManagerClient* client = | |
| 431 ChromePasswordManagerClient::FromWebContents(active_web_contents()); | |
| 432 | |
| 433 // Optionally set up a Mojo connection to the CredentialManagerImpl ahead of | |
| 434 // time, instead of letting it be established on-demand when the call to | |
| 435 // store() triggered from the unload handler. | |
| 436 if (preestablish_mojo_pipe) { | |
| 437 EXPECT_FALSE(client->has_binding_for_credential_manager()); | |
| 438 ASSERT_NO_FATAL_FAILURE( | |
| 439 TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 440 active_web_contents(), false)); | |
| 441 EXPECT_TRUE(client->has_binding_for_credential_manager()); | |
| 442 } | |
| 443 | |
| 444 // Schedule storing a credential on the `unload` event. | |
| 445 ASSERT_NO_FATAL_FAILURE(ScheduleNavigatorStoreCredentialAtUnload( | |
| 446 active_web_contents(), "user", "hunter2")); | |
| 447 | |
| 448 // Trigger a cross-site navigation that is carried out in a new renderer, | |
| 449 // and which will swap out the old RenderFrameHost. | |
| 450 RenderFrameHostDestructionObserver rfh_destruction_observer( | |
| 451 active_web_contents()->GetMainFrame()); | |
| 452 ui_test_utils::NavigateToURL(browser(), b_url); | |
| 453 | |
| 454 // Ensure that the navigator.credentials.store() call is never serviced. | |
|
vasilii
2017/06/29 11:59:59
Why can't the same scenario as in the previous tes
engedy
2017/06/30 19:41:55
It's channel is disconnected in DidFinishNavigatio
| |
| 455 // The sufficient conditions for this are: | |
| 456 // -- The swapped out RFH is destroyed, so the RenderFrame cannot establish | |
| 457 // a new Mojo connection to CredentialManagerImpl anymore. | |
| 458 // -- There is no already existing Mojo connection to CredentialManagerImpl | |
| 459 // either, which could be used to call store() in the future. | |
| 460 // -- There have not been any calls to store() in the past. | |
| 461 rfh_destruction_observer.WaitForDestruction(); | |
| 462 base::RunLoop().RunUntilIdle(); | |
|
vasilii
2017/06/29 11:59:59
Unnecessary I think.
engedy
2017/06/30 19:41:55
Done.
| |
| 463 EXPECT_FALSE(client->has_binding_for_credential_manager()); | |
| 464 EXPECT_FALSE(client->was_store_ever_called()); | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 // Regression test for https://crbug.com/736357. | |
| 469 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, | |
| 470 MojoConnectionRecreatedAfterNavigation) { | |
| 471 const GURL a_url1 = https_test_server().GetURL("a.com", "/title1.html"); | |
| 472 const GURL a_url2 = https_test_server().GetURL("a.com", "/title2.html"); | |
| 473 const GURL a_url2_ref = https_test_server().GetURL("a.com", "/title2.html#r"); | |
| 474 const GURL b_url = https_test_server().GetURL("b.com", "/title2.html#ref"); | |
| 475 | |
| 476 // Enable 'auto signin' for the profile. | |
| 477 password_bubble_experiment::RecordAutoSignInPromptFirstRunExperienceWasShown( | |
| 478 browser()->profile()->GetPrefs()); | |
| 479 | |
| 480 // Navigate to a mostly empty page. | |
| 481 ui_test_utils::NavigateToURL(browser(), a_url1); | |
| 482 | |
| 483 ChromePasswordManagerClient* client = | |
| 484 ChromePasswordManagerClient::FromWebContents(active_web_contents()); | |
| 485 | |
| 486 // Store a credential, and expect it to establish the Mojo connection. | |
| 487 EXPECT_FALSE(client->has_binding_for_credential_manager()); | |
| 488 EXPECT_FALSE(client->was_store_ever_called()); | |
| 489 | |
| 490 ASSERT_TRUE(content::ExecuteScript( | |
| 491 active_web_contents(), | |
| 492 "var c = new PasswordCredential({ id: 'user', password: 'hunter2' });" | |
| 493 "navigator.credentials.store(c);")); | |
| 494 | |
| 495 BubbleObserver prompt_observer(active_web_contents()); | |
|
vasilii
2017/06/29 11:59:59
Please use WebContents() for the reasons stated ab
engedy
2017/06/30 19:41:55
Done.
| |
| 496 prompt_observer.WaitForSavePrompt(); | |
| 497 ASSERT_TRUE(prompt_observer.IsShowingSavePrompt()); | |
| 498 prompt_observer.AcceptSavePrompt(); | |
| 499 WaitForPasswordStore(); | |
| 500 | |
| 501 EXPECT_TRUE(client->has_binding_for_credential_manager()); | |
| 502 EXPECT_TRUE(client->was_store_ever_called()); | |
| 503 | |
| 504 // Trigger a same-site navigation. | |
| 505 content::RenderFrameHost* old_rfh = active_web_contents()->GetMainFrame(); | |
| 506 ui_test_utils::NavigateToURL(browser(), a_url2); | |
| 507 base::RunLoop().RunUntilIdle(); | |
|
vasilii
2017/06/29 12:00:00
ditto
engedy
2017/06/30 19:41:55
Done.
| |
| 508 ASSERT_EQ(old_rfh, active_web_contents()->GetMainFrame()); | |
| 509 | |
| 510 // Expect the Mojo connection closed. | |
| 511 EXPECT_FALSE(client->has_binding_for_credential_manager()); | |
| 512 | |
| 513 // Calling navigator.credentials.get() again should re-establish the Mojo | |
| 514 // connection and succeed. | |
| 515 ASSERT_NO_FATAL_FAILURE( | |
| 516 TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 517 active_web_contents(), true)); | |
| 518 EXPECT_TRUE(client->has_binding_for_credential_manager()); | |
| 519 | |
| 520 // Same-document navigation. Call to get() succeeds. | |
| 521 ui_test_utils::NavigateToURL(browser(), a_url2_ref); | |
| 522 ASSERT_EQ(old_rfh, active_web_contents()->GetMainFrame()); | |
|
vasilii
2017/06/29 12:00:00
Do you want to check the connection?
engedy
2017/06/30 19:41:55
Done.
| |
| 523 ASSERT_NO_FATAL_FAILURE( | |
| 524 TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 525 active_web_contents(), true)); | |
| 526 | |
| 527 // Cross-site navigation. Call to get() succeeds without results. | |
| 528 ui_test_utils::NavigateToURL(browser(), b_url); | |
| 529 ASSERT_NO_FATAL_FAILURE( | |
| 530 TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 531 active_web_contents(), false)); | |
| 532 | |
| 533 // Trigger a cross-site navigation back. Call to get() should still succeed, | |
| 534 // and once again with results. | |
| 535 ui_test_utils::NavigateToURL(browser(), a_url1); | |
| 536 ASSERT_NO_FATAL_FAILURE( | |
| 537 TriggerNavigatorGetPasswordCredentialsAndExpectHasResult( | |
| 538 active_web_contents(), true)); | |
| 539 } | |
| 540 | |
| 248 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, SaveViaAPIAndAutofill) { | 541 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, SaveViaAPIAndAutofill) { |
| 249 NavigateToFile("/password/password_form.html"); | 542 NavigateToFile("/password/password_form.html"); |
| 250 | 543 |
| 251 ASSERT_TRUE(content::ExecuteScript( | 544 ASSERT_TRUE(content::ExecuteScript( |
| 252 RenderViewHost(), | 545 RenderViewHost(), |
| 253 "document.getElementById('input_submit_button').addEventListener('click'," | 546 "document.getElementById('input_submit_button').addEventListener('click'," |
| 254 "function(event) {" | 547 "function(event) {" |
| 255 "var c = new PasswordCredential({ id: 'user', password: 'API' });" | 548 "var c = new PasswordCredential({ id: 'user', password: 'API' });" |
| 256 "navigator.credentials.store(c);" | 549 "navigator.credentials.store(c);" |
| 257 "});")); | 550 "});")); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 | 642 |
| 350 // Reload the page and make sure it's autofilled. | 643 // Reload the page and make sure it's autofilled. |
| 351 NavigateToFile("/password/password_form.html"); | 644 NavigateToFile("/password/password_form.html"); |
| 352 WaitForElementValue("username_field", "user"); | 645 WaitForElementValue("username_field", "user"); |
| 353 content::SimulateMouseClickAt( | 646 content::SimulateMouseClickAt( |
| 354 WebContents(), 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(1, 1)); | 647 WebContents(), 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(1, 1)); |
| 355 WaitForElementValue("password_field", "12345"); | 648 WaitForElementValue("password_field", "12345"); |
| 356 } | 649 } |
| 357 | 650 |
| 358 } // namespace | 651 } // namespace |
| OLD | NEW |