| 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/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/strings/string_number_conversions.h" | 6 #include "base/strings/string_number_conversions.h" |
| 7 #include "base/test/scoped_feature_list.h" |
| 8 #include "chrome/browser/password_manager/chrome_password_manager_client.h" |
| 7 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsert
est_util.h" | 9 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsert
est_util.h" |
| 8 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
| 9 #include "chrome/browser/ui/browser_window.h" | 11 #include "chrome/browser/ui/browser_window.h" |
| 10 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" | 12 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" |
| 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 13 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 12 #include "chrome/test/base/in_process_browser_test.h" | 14 #include "chrome/test/base/in_process_browser_test.h" |
| 13 #include "chrome/test/base/interactive_test_utils.h" | 15 #include "chrome/test/base/interactive_test_utils.h" |
| 14 #include "chrome/test/base/ui_test_utils.h" | 16 #include "chrome/test/base/ui_test_utils.h" |
| 17 #include "components/autofill/core/browser/autofill_client.h" |
| 18 #include "components/autofill/core/browser/test_autofill_client.h" |
| 15 #include "components/guest_view/browser/guest_view_manager_delegate.h" | 19 #include "components/guest_view/browser/guest_view_manager_delegate.h" |
| 16 #include "components/guest_view/browser/test_guest_view_manager.h" | 20 #include "components/guest_view/browser/test_guest_view_manager.h" |
| 21 #include "components/security_state/core/security_state.h" |
| 22 #include "content/public/browser/focused_node_details.h" |
| 17 #include "content/public/browser/navigation_handle.h" | 23 #include "content/public/browser/navigation_handle.h" |
| 24 #include "content/public/browser/notification_details.h" |
| 25 #include "content/public/browser/notification_observer.h" |
| 26 #include "content/public/browser/notification_registrar.h" |
| 27 #include "content/public/browser/notification_service.h" |
| 28 #include "content/public/browser/notification_source.h" |
| 18 #include "content/public/browser/render_frame_host.h" | 29 #include "content/public/browser/render_frame_host.h" |
| 19 #include "content/public/browser/render_widget_host.h" | 30 #include "content/public/browser/render_widget_host.h" |
| 20 #include "content/public/browser/render_widget_host_view.h" | 31 #include "content/public/browser/render_widget_host_view.h" |
| 21 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 22 #include "content/public/test/browser_test_utils.h" | 33 #include "content/public/test/browser_test_utils.h" |
| 23 #include "content/public/test/content_browser_test_utils.h" | 34 #include "content/public/test/content_browser_test_utils.h" |
| 24 #include "content/public/test/test_navigation_observer.h" | 35 #include "content/public/test/test_navigation_observer.h" |
| 25 #include "content/public/test/test_utils.h" | 36 #include "content/public/test/test_utils.h" |
| 26 #include "extensions/browser/api/extensions_api_client.h" | 37 #include "extensions/browser/api/extensions_api_client.h" |
| 27 #include "extensions/common/constants.h" | 38 #include "extensions/common/constants.h" |
| 28 #include "net/dns/mock_host_resolver.h" | 39 #include "net/dns/mock_host_resolver.h" |
| 29 #include "net/test/embedded_test_server/embedded_test_server.h" | 40 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 30 #include "ui/display/display.h" | 41 #include "ui/display/display.h" |
| 31 #include "ui/display/screen.h" | 42 #include "ui/display/screen.h" |
| 43 #include "ui/gfx/geometry/point.h" |
| 44 #include "ui/gfx/geometry/rect.h" |
| 45 #include "ui/gfx/geometry/vector2d.h" |
| 32 #include "url/gurl.h" | 46 #include "url/gurl.h" |
| 33 | 47 |
| 48 namespace autofill { |
| 49 class AutofillPopupDelegate; |
| 50 struct Suggestion; |
| 51 } |
| 52 |
| 34 class SitePerProcessInteractiveBrowserTest : public InProcessBrowserTest { | 53 class SitePerProcessInteractiveBrowserTest : public InProcessBrowserTest { |
| 35 public: | 54 public: |
| 36 SitePerProcessInteractiveBrowserTest() {} | 55 SitePerProcessInteractiveBrowserTest() {} |
| 37 ~SitePerProcessInteractiveBrowserTest() override {} | 56 ~SitePerProcessInteractiveBrowserTest() override {} |
| 38 | 57 |
| 39 void SetUpCommandLine(base::CommandLine* command_line) override { | 58 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 40 content::IsolateAllSitesForTesting(command_line); | 59 content::IsolateAllSitesForTesting(command_line); |
| 41 } | 60 } |
| 42 | 61 |
| 43 void SetUpOnMainThread() override { | 62 void SetUpOnMainThread() override { |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20, | 936 send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20, |
| 918 blink::WebInputEvent::MouseUp); | 937 blink::WebInputEvent::MouseUp); |
| 919 menu_waiter.WaitForMenuOpenAndClose(); | 938 menu_waiter.WaitForMenuOpenAndClose(); |
| 920 | 939 |
| 921 gfx::Point point_in_root_window = | 940 gfx::Point point_in_root_window = |
| 922 child_view->TransformPointToRootCoordSpace(gfx::Point(10, 20)); | 941 child_view->TransformPointToRootCoordSpace(gfx::Point(10, 20)); |
| 923 | 942 |
| 924 EXPECT_EQ(point_in_root_window.x(), menu_waiter.params().x); | 943 EXPECT_EQ(point_in_root_window.x(), menu_waiter.params().x); |
| 925 EXPECT_EQ(point_in_root_window.y(), menu_waiter.params().y); | 944 EXPECT_EQ(point_in_root_window.y(), menu_waiter.params().y); |
| 926 } | 945 } |
| 946 |
| 947 class SitePerProcessAutofillTest : public SitePerProcessInteractiveBrowserTest { |
| 948 public: |
| 949 SitePerProcessAutofillTest() : SitePerProcessInteractiveBrowserTest() {} |
| 950 ~SitePerProcessAutofillTest() override{}; |
| 951 |
| 952 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 953 SitePerProcessInteractiveBrowserTest::SetUpCommandLine(command_line); |
| 954 // We need to set the feature state before the render process is created, |
| 955 // in order for it to inherit the feature state from the browser process. |
| 956 // SetUp() runs too early, and SetUpOnMainThread() runs too late. |
| 957 scoped_feature_list_.InitAndEnableFeature( |
| 958 security_state::kHttpFormWarningFeature); |
| 959 } |
| 960 |
| 961 protected: |
| 962 class TestAutofillClient : public autofill::TestAutofillClient { |
| 963 public: |
| 964 TestAutofillClient() : popup_shown_(false){}; |
| 965 ~TestAutofillClient() override {} |
| 966 |
| 967 void WaitForNextPopup() { |
| 968 if (popup_shown_) |
| 969 return; |
| 970 loop_runner_ = new content::MessageLoopRunner(); |
| 971 loop_runner_->Run(); |
| 972 } |
| 973 |
| 974 void ShowAutofillPopup( |
| 975 const gfx::RectF& element_bounds, |
| 976 base::i18n::TextDirection text_direction, |
| 977 const std::vector<autofill::Suggestion>& suggestions, |
| 978 base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override { |
| 979 element_bounds_ = element_bounds; |
| 980 popup_shown_ = true; |
| 981 if (loop_runner_) |
| 982 loop_runner_->Quit(); |
| 983 } |
| 984 |
| 985 const gfx::RectF& last_element_bounds() const { return element_bounds_; } |
| 986 |
| 987 private: |
| 988 gfx::RectF element_bounds_; |
| 989 bool popup_shown_; |
| 990 scoped_refptr<content::MessageLoopRunner> loop_runner_; |
| 991 |
| 992 DISALLOW_COPY_AND_ASSIGN(TestAutofillClient); |
| 993 }; |
| 994 |
| 995 const int kIframeTopDisplacement = 150; |
| 996 const int kIframeLeftDisplacement = 200; |
| 997 |
| 998 void SetupMainTab() { |
| 999 // Add a fresh new WebContents for which we add our own version of the |
| 1000 // ChromePasswordManagerClient that uses a custom TestAutofillClient. |
| 1001 content::WebContents* new_contents = content::WebContents::Create( |
| 1002 content::WebContents::CreateParams(browser() |
| 1003 ->tab_strip_model() |
| 1004 ->GetActiveWebContents() |
| 1005 ->GetBrowserContext())); |
| 1006 ASSERT_TRUE(new_contents); |
| 1007 ASSERT_FALSE(ChromePasswordManagerClient::FromWebContents(new_contents)); |
| 1008 |
| 1009 // Create ChromePasswordManagerClient and verify it exists for the new |
| 1010 // WebContents. |
| 1011 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( |
| 1012 new_contents, &test_autofill_client_); |
| 1013 ASSERT_TRUE(ChromePasswordManagerClient::FromWebContents(new_contents)); |
| 1014 |
| 1015 browser()->tab_strip_model()->AppendWebContents(new_contents, true); |
| 1016 } |
| 1017 |
| 1018 TestAutofillClient& autofill_client() { return test_autofill_client_; } |
| 1019 |
| 1020 private: |
| 1021 base::test::ScopedFeatureList scoped_feature_list_; |
| 1022 TestAutofillClient test_autofill_client_; |
| 1023 |
| 1024 DISALLOW_COPY_AND_ASSIGN(SitePerProcessAutofillTest); |
| 1025 }; |
| 1026 |
| 1027 // Observes the notifications for changes in focused node/element in the page. |
| 1028 class FocusedEditableNodeChangedObserver : content::NotificationObserver { |
| 1029 public: |
| 1030 FocusedEditableNodeChangedObserver() : observed_(false) { |
| 1031 registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, |
| 1032 content::NotificationService::AllSources()); |
| 1033 } |
| 1034 ~FocusedEditableNodeChangedObserver() override {} |
| 1035 |
| 1036 void WaitForFocusChangeInPage() { |
| 1037 if (observed_) |
| 1038 return; |
| 1039 loop_runner_ = new content::MessageLoopRunner(); |
| 1040 loop_runner_->Run(); |
| 1041 } |
| 1042 |
| 1043 // content::NotificationObserver override. |
| 1044 void Observe(int type, |
| 1045 const content::NotificationSource& source, |
| 1046 const content::NotificationDetails& details) override { |
| 1047 auto focused_node_details = |
| 1048 content::Details<content::FocusedNodeDetails>(details); |
| 1049 if (!focused_node_details->is_editable_node) |
| 1050 return; |
| 1051 focused_node_bounds_in_screen_ = |
| 1052 focused_node_details->node_bounds_in_screen.origin(); |
| 1053 observed_ = true; |
| 1054 if (loop_runner_) |
| 1055 loop_runner_->Quit(); |
| 1056 } |
| 1057 |
| 1058 const gfx::Point& focused_node_bounds_in_screen() const { |
| 1059 return focused_node_bounds_in_screen_; |
| 1060 } |
| 1061 |
| 1062 private: |
| 1063 content::NotificationRegistrar registrar_; |
| 1064 bool observed_; |
| 1065 gfx::Point focused_node_bounds_in_screen_; |
| 1066 scoped_refptr<content::MessageLoopRunner> loop_runner_; |
| 1067 |
| 1068 DISALLOW_COPY_AND_ASSIGN(FocusedEditableNodeChangedObserver); |
| 1069 }; |
| 1070 |
| 1071 // This test verifies that displacements (margin, etc) in the position of an |
| 1072 // OOPIF is considered when showing an AutofillClient warning pop-up for |
| 1073 // unsecure web sites. |
| 1074 IN_PROC_BROWSER_TEST_F(SitePerProcessAutofillTest, |
| 1075 PasswordAutofillPopupPositionInsideOOPIF) { |
| 1076 SetupMainTab(); |
| 1077 ASSERT_TRUE( |
| 1078 base::FeatureList::IsEnabled(security_state::kHttpFormWarningFeature)); |
| 1079 |
| 1080 GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html")); |
| 1081 ui_test_utils::NavigateToURL(browser(), main_url); |
| 1082 content::WebContents* active_web_contents = |
| 1083 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1084 |
| 1085 // Add some displacement for <iframe>. |
| 1086 ASSERT_TRUE(content::ExecuteScript( |
| 1087 active_web_contents, |
| 1088 base::StringPrintf("var iframe = document.querySelector('iframe');" |
| 1089 "iframe.style.marginTop = '%dpx';" |
| 1090 "iframe.style.marginLeft = '%dpx';", |
| 1091 kIframeTopDisplacement, kIframeLeftDisplacement))); |
| 1092 |
| 1093 // Navigate the <iframe> to a simple page. |
| 1094 GURL frame_url = embedded_test_server()->GetURL("b.com", "/title1.html"); |
| 1095 EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url)); |
| 1096 content::RenderFrameHost* child_frame = content::FrameMatchingPredicate( |
| 1097 active_web_contents, base::Bind(&content::FrameIsChildOfMainFrame)); |
| 1098 |
| 1099 // We will need to listen to focus changes to find out about the container |
| 1100 // bounds of any focused <input> elements on the page. |
| 1101 FocusedEditableNodeChangedObserver focus_observer; |
| 1102 |
| 1103 // Focus the child frame, add an <input> with type "password", and focus it. |
| 1104 ASSERT_TRUE(ExecuteScript(child_frame, |
| 1105 "window.focus();" |
| 1106 "var input = document.createElement('input');" |
| 1107 "input.type = 'password';" |
| 1108 "document.body.appendChild(input);" |
| 1109 "input.focus();")); |
| 1110 focus_observer.WaitForFocusChangeInPage(); |
| 1111 |
| 1112 // The user gesture (input) should lead to a security warning. |
| 1113 content::SimulateKeyPress(active_web_contents, ui::DomKey::FromCharacter('A'), |
| 1114 ui::DomCode::US_A, ui::VKEY_A, false, false, false, |
| 1115 false); |
| 1116 autofill_client().WaitForNextPopup(); |
| 1117 |
| 1118 gfx::Point bounds_origin( |
| 1119 static_cast<int>(autofill_client().last_element_bounds().origin().x()), |
| 1120 static_cast<int>(autofill_client().last_element_bounds().origin().y())); |
| 1121 |
| 1122 // Convert the bounds to screen coordinates (to then compare against the ones |
| 1123 // reported by focus change observer). |
| 1124 bounds_origin += active_web_contents->GetRenderWidgetHostView() |
| 1125 ->GetViewBounds() |
| 1126 .OffsetFromOrigin(); |
| 1127 |
| 1128 gfx::Vector2d error = |
| 1129 bounds_origin - focus_observer.focused_node_bounds_in_screen(); |
| 1130 |
| 1131 // Ideally, the length of the error vector should be 0.0f. But due to |
| 1132 // potential rounding errors, we assume a larger limit (which is slightly |
| 1133 // larger than square root of 2). |
| 1134 EXPECT_LT(error.Length(), 1.4143f) |
| 1135 << "Origin of bounds from focused node changed event is '" |
| 1136 << focus_observer.focused_node_bounds_in_screen().ToString() |
| 1137 << "' but AutofillClient is reporting '" << bounds_origin.ToString() |
| 1138 << "'"; |
| 1139 } |
| OLD | NEW |