| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/files/file_path.h" | 6 #include "base/files/file_path.h" |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/test/scoped_feature_list.h" |
| 10 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
| 11 #include "chrome/browser/external_protocol/external_protocol_handler.h" | 12 #include "chrome/browser/external_protocol/external_protocol_handler.h" |
| 12 #include "chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h" | 13 #include "chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h" |
| 14 #include "chrome/browser/password_manager/chrome_password_manager_client.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
| 15 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 17 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 16 #include "chrome/test/base/in_process_browser_test.h" | 18 #include "chrome/test/base/in_process_browser_test.h" |
| 17 #include "chrome/test/base/ui_test_utils.h" | 19 #include "chrome/test/base/ui_test_utils.h" |
| 20 #include "components/autofill/core/browser/autofill_client.h" |
| 21 #include "components/autofill/core/browser/test_autofill_client.h" |
| 18 #include "components/guest_view/browser/guest_view_manager_delegate.h" | 22 #include "components/guest_view/browser/guest_view_manager_delegate.h" |
| 19 #include "components/guest_view/browser/test_guest_view_manager.h" | 23 #include "components/guest_view/browser/test_guest_view_manager.h" |
| 24 #include "components/security_state/core/security_state.h" |
| 25 #include "content/public/browser/focused_node_details.h" |
| 20 #include "content/public/browser/interstitial_page.h" | 26 #include "content/public/browser/interstitial_page.h" |
| 27 #include "content/public/browser/notification_details.h" |
| 21 #include "content/public/browser/notification_observer.h" | 28 #include "content/public/browser/notification_observer.h" |
| 29 #include "content/public/browser/notification_registrar.h" |
| 22 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| 31 #include "content/public/browser/notification_source.h" |
| 23 #include "content/public/browser/notification_types.h" | 32 #include "content/public/browser/notification_types.h" |
| 24 #include "content/public/browser/render_frame_host.h" | 33 #include "content/public/browser/render_frame_host.h" |
| 34 #include "content/public/browser/render_widget_host_view.h" |
| 25 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
| 26 #include "content/public/browser/web_contents_observer.h" | 36 #include "content/public/browser/web_contents_observer.h" |
| 27 #include "content/public/test/browser_test_utils.h" | 37 #include "content/public/test/browser_test_utils.h" |
| 28 #include "content/public/test/content_browser_test_utils.h" | 38 #include "content/public/test/content_browser_test_utils.h" |
| 29 #include "content/public/test/test_utils.h" | 39 #include "content/public/test/test_utils.h" |
| 30 #include "extensions/browser/api/extensions_api_client.h" | 40 #include "extensions/browser/api/extensions_api_client.h" |
| 31 #include "net/dns/mock_host_resolver.h" | 41 #include "net/dns/mock_host_resolver.h" |
| 32 #include "net/test/embedded_test_server/embedded_test_server.h" | 42 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 33 #include "ui/display/display_switches.h" | 43 #include "ui/display/display_switches.h" |
| 44 #include "ui/gfx/geometry/point.h" |
| 45 #include "ui/gfx/geometry/rect.h" |
| 46 #include "ui/gfx/geometry/vector2d.h" |
| 34 #include "url/gurl.h" | 47 #include "url/gurl.h" |
| 35 | 48 |
| 49 namespace autofill { |
| 50 class AutofillPopupDelegate; |
| 51 struct Suggestion; |
| 52 } |
| 53 |
| 36 class ChromeSitePerProcessTest : public InProcessBrowserTest { | 54 class ChromeSitePerProcessTest : public InProcessBrowserTest { |
| 37 public: | 55 public: |
| 38 ChromeSitePerProcessTest() {} | 56 ChromeSitePerProcessTest() {} |
| 39 ~ChromeSitePerProcessTest() override {} | 57 ~ChromeSitePerProcessTest() override {} |
| 40 | 58 |
| 41 void SetUpCommandLine(base::CommandLine* command_line) override { | 59 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 42 content::IsolateAllSitesForTesting(command_line); | 60 content::IsolateAllSitesForTesting(command_line); |
| 43 } | 61 } |
| 44 | 62 |
| 45 void SetUpOnMainThread() override { | 63 void SetUpOnMainThread() override { |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 "document.querySelector('iframe').src = '" + frame_url.spec() + "';\n" | 511 "document.querySelector('iframe').src = '" + frame_url.spec() + "';\n" |
| 494 "var w = window.open('about:blank');\n" | 512 "var w = window.open('about:blank');\n" |
| 495 "window.domAutomationController.send(!!w);\n", | 513 "window.domAutomationController.send(!!w);\n", |
| 496 &popup_handle_is_valid)); | 514 &popup_handle_is_valid)); |
| 497 popup_observer.Wait(); | 515 popup_observer.Wait(); |
| 498 | 516 |
| 499 // The popup shouldn't be blocked. | 517 // The popup shouldn't be blocked. |
| 500 EXPECT_TRUE(popup_handle_is_valid); | 518 EXPECT_TRUE(popup_handle_is_valid); |
| 501 ASSERT_EQ(2, browser()->tab_strip_model()->count()); | 519 ASSERT_EQ(2, browser()->tab_strip_model()->count()); |
| 502 } | 520 } |
| 521 |
| 522 class ChromeSitePerProcessAutofillTest : public ChromeSitePerProcessTest { |
| 523 public: |
| 524 ChromeSitePerProcessAutofillTest() : ChromeSitePerProcessTest() {} |
| 525 ~ChromeSitePerProcessAutofillTest() override{}; |
| 526 |
| 527 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 528 ChromeSitePerProcessTest::SetUpCommandLine(command_line); |
| 529 // We need to set the feature state before the render process is created, |
| 530 // in order for it to inherit the feature state from the browser process. |
| 531 // SetUp() runs too early, and SetUpOnMainThread() runs too late. |
| 532 scoped_feature_list_.InitAndEnableFeature( |
| 533 security_state::kHttpFormWarningFeature); |
| 534 } |
| 535 |
| 536 void SetUpOnMainThread() override { |
| 537 ChromeSitePerProcessTest::SetUpOnMainThread(); |
| 538 } |
| 539 |
| 540 protected: |
| 541 class TestAutofillClient : public autofill::TestAutofillClient { |
| 542 public: |
| 543 TestAutofillClient() : popup_shown_(false){}; |
| 544 ~TestAutofillClient() override {} |
| 545 |
| 546 void WaitForNextPopup() { |
| 547 if (popup_shown_) |
| 548 return; |
| 549 loop_runner_ = new content::MessageLoopRunner(); |
| 550 loop_runner_->Run(); |
| 551 } |
| 552 |
| 553 void ShowAutofillPopup( |
| 554 const gfx::RectF& element_bounds, |
| 555 base::i18n::TextDirection text_direction, |
| 556 const std::vector<autofill::Suggestion>& suggestions, |
| 557 base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override { |
| 558 element_bounds_ = element_bounds; |
| 559 popup_shown_ = true; |
| 560 if (loop_runner_) |
| 561 loop_runner_->Quit(); |
| 562 } |
| 563 |
| 564 const gfx::RectF& last_element_bounds() const { return element_bounds_; } |
| 565 |
| 566 private: |
| 567 gfx::RectF element_bounds_; |
| 568 bool popup_shown_; |
| 569 scoped_refptr<content::MessageLoopRunner> loop_runner_; |
| 570 |
| 571 DISALLOW_COPY_AND_ASSIGN(TestAutofillClient); |
| 572 }; |
| 573 |
| 574 const int kIframeTopDisplacement = 150; |
| 575 const int kIframeLeftDisplacement = 200; |
| 576 |
| 577 void SetupMainTab() { |
| 578 // Add a fresh new WebContents for which we add our own version of the |
| 579 // ChromePasswordManagerClient that uses a custom TestAutofillClient. |
| 580 content::WebContents* new_contents = content::WebContents::Create( |
| 581 content::WebContents::CreateParams(browser() |
| 582 ->tab_strip_model() |
| 583 ->GetActiveWebContents() |
| 584 ->GetBrowserContext())); |
| 585 ASSERT_TRUE(new_contents); |
| 586 ASSERT_FALSE(ChromePasswordManagerClient::FromWebContents(new_contents)); |
| 587 |
| 588 // Create ChromePasswordManagerClient and verify it exists for the new |
| 589 // WebContents. |
| 590 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( |
| 591 new_contents, &test_autofill_client_); |
| 592 ASSERT_TRUE(ChromePasswordManagerClient::FromWebContents(new_contents)); |
| 593 |
| 594 browser()->tab_strip_model()->AppendWebContents(new_contents, true); |
| 595 } |
| 596 |
| 597 TestAutofillClient& autofill_client() { return test_autofill_client_; } |
| 598 |
| 599 private: |
| 600 base::test::ScopedFeatureList scoped_feature_list_; |
| 601 TestAutofillClient test_autofill_client_; |
| 602 |
| 603 DISALLOW_COPY_AND_ASSIGN(ChromeSitePerProcessAutofillTest); |
| 604 }; |
| 605 |
| 606 // Observes the notifications for changes in focused node/element in the page. |
| 607 // The notification contains |
| 608 class FocusedEditableNodeChangedObserver : content::NotificationObserver { |
| 609 public: |
| 610 FocusedEditableNodeChangedObserver() : observed_(false) { |
| 611 registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, |
| 612 content::NotificationService::AllSources()); |
| 613 } |
| 614 ~FocusedEditableNodeChangedObserver() override {} |
| 615 |
| 616 void WaitForFocusChangeInPage() { |
| 617 if (observed_) |
| 618 return; |
| 619 loop_runner_ = new content::MessageLoopRunner(); |
| 620 loop_runner_->Run(); |
| 621 } |
| 622 |
| 623 // content::NotificationObserver override. |
| 624 void Observe(int type, |
| 625 const content::NotificationSource& source, |
| 626 const content::NotificationDetails& details) override { |
| 627 auto focused_node_details = |
| 628 content::Details<content::FocusedNodeDetails>(details); |
| 629 if (!focused_node_details->is_editable_node) |
| 630 return; |
| 631 focused_node_bounds_in_screen_ = |
| 632 focused_node_details->node_bounds_in_screen.origin(); |
| 633 observed_ = true; |
| 634 if (loop_runner_) |
| 635 loop_runner_->Quit(); |
| 636 } |
| 637 |
| 638 const gfx::Point& focused_node_bounds_in_screen() const { |
| 639 return focused_node_bounds_in_screen_; |
| 640 } |
| 641 |
| 642 private: |
| 643 content::NotificationRegistrar registrar_; |
| 644 bool observed_; |
| 645 gfx::Point focused_node_bounds_in_screen_; |
| 646 scoped_refptr<content::MessageLoopRunner> loop_runner_; |
| 647 |
| 648 DISALLOW_COPY_AND_ASSIGN(FocusedEditableNodeChangedObserver); |
| 649 }; |
| 650 |
| 651 // This test verifies that displacements (margin, etc) in the position of an |
| 652 // OOPIF is considered when showing an AutofillClient warning pop-up for |
| 653 // unsecure web sites. |
| 654 IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessAutofillTest, |
| 655 AutofillClientPositionWhenInsideOOPIF) { |
| 656 SetupMainTab(); |
| 657 ASSERT_TRUE( |
| 658 base::FeatureList::IsEnabled(security_state::kHttpFormWarningFeature)); |
| 659 |
| 660 GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html")); |
| 661 ui_test_utils::NavigateToURL(browser(), main_url); |
| 662 content::WebContents* active_web_contents = |
| 663 browser()->tab_strip_model()->GetActiveWebContents(); |
| 664 |
| 665 // Add some displacement for <iframe>. |
| 666 ASSERT_TRUE(content::ExecuteScript( |
| 667 active_web_contents, |
| 668 base::StringPrintf("var iframe = document.querySelector('iframe');" |
| 669 "iframe.style.marginTop = '%dpx';" |
| 670 "iframe.style.marginLeft = '%dpx';", |
| 671 kIframeTopDisplacement, kIframeLeftDisplacement))); |
| 672 |
| 673 // Navigate the <iframe> to a simple page. |
| 674 GURL frame_url = embedded_test_server()->GetURL("b.com", "/title1.html"); |
| 675 EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url)); |
| 676 content::RenderFrameHost* child_frame = content::FrameMatchingPredicate( |
| 677 active_web_contents, base::Bind(&content::FrameIsChildOfMainFrame)); |
| 678 |
| 679 // We will need to listen to focus changes to find out about the container |
| 680 // bounds of any focused <input> elements on the page. |
| 681 FocusedEditableNodeChangedObserver focus_observer; |
| 682 |
| 683 // Focus the child frame, add an <input> with type "password", and focus it. |
| 684 ASSERT_TRUE(ExecuteScript(child_frame, |
| 685 "window.focus();" |
| 686 "var input = document.createElement('input');" |
| 687 "input.type = 'password';" |
| 688 "document.body.appendChild(input);" |
| 689 "input.focus();")); |
| 690 focus_observer.WaitForFocusChangeInPage(); |
| 691 |
| 692 // The user gesture (input) should lead to a security warning. |
| 693 content::SimulateKeyPress(active_web_contents, ui::DomKey::FromCharacter('A'), |
| 694 ui::DomCode::US_A, ui::VKEY_A, false, false, false, |
| 695 false); |
| 696 autofill_client().WaitForNextPopup(); |
| 697 |
| 698 gfx::Point bounds_origin( |
| 699 static_cast<int>(autofill_client().last_element_bounds().origin().x()), |
| 700 static_cast<int>(autofill_client().last_element_bounds().origin().y())); |
| 701 |
| 702 // Convert the bounds to screen coordinates (to then compare against the ones |
| 703 // reported by focus change observer). |
| 704 bounds_origin += active_web_contents->GetRenderWidgetHostView() |
| 705 ->GetViewBounds() |
| 706 .OffsetFromOrigin(); |
| 707 |
| 708 gfx::Vector2d error = |
| 709 bounds_origin - focus_observer.focused_node_bounds_in_screen(); |
| 710 |
| 711 // Ideally, the length of the error vector should be 0.0f. But due to |
| 712 // potential rounding errors, we assume a larger limit (which is slightly |
| 713 // larger than square root of 2). |
| 714 EXPECT_LT(error.Length(), 1.4143f); |
| 715 } |
| OLD | NEW |