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/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 // The notification contains | |
|
alexmos
2017/03/24 18:10:21
nit: unfinished sentence. It was that way before,
EhsanK
2017/03/24 19:37:15
Thanks for catching this. Done.
| |
| 1029 class FocusedEditableNodeChangedObserver : content::NotificationObserver { | |
| 1030 public: | |
| 1031 FocusedEditableNodeChangedObserver() : observed_(false) { | |
| 1032 registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, | |
| 1033 content::NotificationService::AllSources()); | |
| 1034 } | |
| 1035 ~FocusedEditableNodeChangedObserver() override {} | |
| 1036 | |
| 1037 void WaitForFocusChangeInPage() { | |
| 1038 if (observed_) | |
| 1039 return; | |
| 1040 loop_runner_ = new content::MessageLoopRunner(); | |
| 1041 loop_runner_->Run(); | |
| 1042 } | |
| 1043 | |
| 1044 // content::NotificationObserver override. | |
| 1045 void Observe(int type, | |
| 1046 const content::NotificationSource& source, | |
| 1047 const content::NotificationDetails& details) override { | |
| 1048 auto focused_node_details = | |
| 1049 content::Details<content::FocusedNodeDetails>(details); | |
| 1050 if (!focused_node_details->is_editable_node) | |
| 1051 return; | |
| 1052 focused_node_bounds_in_screen_ = | |
| 1053 focused_node_details->node_bounds_in_screen.origin(); | |
| 1054 observed_ = true; | |
| 1055 if (loop_runner_) | |
| 1056 loop_runner_->Quit(); | |
| 1057 } | |
| 1058 | |
| 1059 const gfx::Point& focused_node_bounds_in_screen() const { | |
| 1060 return focused_node_bounds_in_screen_; | |
| 1061 } | |
| 1062 | |
| 1063 private: | |
| 1064 content::NotificationRegistrar registrar_; | |
| 1065 bool observed_; | |
| 1066 gfx::Point focused_node_bounds_in_screen_; | |
| 1067 scoped_refptr<content::MessageLoopRunner> loop_runner_; | |
| 1068 | |
| 1069 DISALLOW_COPY_AND_ASSIGN(FocusedEditableNodeChangedObserver); | |
| 1070 }; | |
| 1071 | |
| 1072 // This test verifies that displacements (margin, etc) in the position of an | |
| 1073 // OOPIF is considered when showing an AutofillClient warning pop-up for | |
| 1074 // unsecure web sites. | |
| 1075 IN_PROC_BROWSER_TEST_F(SitePerProcessAutofillTest, | |
| 1076 PasswordAutofillPopupPositionInsideOOPIF) { | |
| 1077 SetupMainTab(); | |
| 1078 ASSERT_TRUE( | |
| 1079 base::FeatureList::IsEnabled(security_state::kHttpFormWarningFeature)); | |
| 1080 | |
| 1081 GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html")); | |
| 1082 ui_test_utils::NavigateToURL(browser(), main_url); | |
| 1083 content::WebContents* active_web_contents = | |
| 1084 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 1085 | |
| 1086 // Add some displacement for <iframe>. | |
| 1087 ASSERT_TRUE(content::ExecuteScript( | |
| 1088 active_web_contents, | |
| 1089 base::StringPrintf("var iframe = document.querySelector('iframe');" | |
| 1090 "iframe.style.marginTop = '%dpx';" | |
| 1091 "iframe.style.marginLeft = '%dpx';", | |
| 1092 kIframeTopDisplacement, kIframeLeftDisplacement))); | |
| 1093 | |
| 1094 // Navigate the <iframe> to a simple page. | |
| 1095 GURL frame_url = embedded_test_server()->GetURL("b.com", "/title1.html"); | |
| 1096 EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url)); | |
| 1097 content::RenderFrameHost* child_frame = content::FrameMatchingPredicate( | |
| 1098 active_web_contents, base::Bind(&content::FrameIsChildOfMainFrame)); | |
| 1099 | |
| 1100 // We will need to listen to focus changes to find out about the container | |
| 1101 // bounds of any focused <input> elements on the page. | |
| 1102 FocusedEditableNodeChangedObserver focus_observer; | |
| 1103 | |
| 1104 // Focus the child frame, add an <input> with type "password", and focus it. | |
| 1105 ASSERT_TRUE(ExecuteScript(child_frame, | |
| 1106 "window.focus();" | |
| 1107 "var input = document.createElement('input');" | |
| 1108 "input.type = 'password';" | |
| 1109 "document.body.appendChild(input);" | |
| 1110 "input.focus();")); | |
| 1111 focus_observer.WaitForFocusChangeInPage(); | |
| 1112 | |
| 1113 // The user gesture (input) should lead to a security warning. | |
| 1114 content::SimulateKeyPress(active_web_contents, ui::DomKey::FromCharacter('A'), | |
| 1115 ui::DomCode::US_A, ui::VKEY_A, false, false, false, | |
| 1116 false); | |
| 1117 autofill_client().WaitForNextPopup(); | |
| 1118 | |
| 1119 gfx::Point bounds_origin( | |
| 1120 static_cast<int>(autofill_client().last_element_bounds().origin().x()), | |
| 1121 static_cast<int>(autofill_client().last_element_bounds().origin().y())); | |
| 1122 | |
| 1123 // Convert the bounds to screen coordinates (to then compare against the ones | |
| 1124 // reported by focus change observer). | |
| 1125 bounds_origin += active_web_contents->GetRenderWidgetHostView() | |
| 1126 ->GetViewBounds() | |
| 1127 .OffsetFromOrigin(); | |
| 1128 | |
| 1129 gfx::Vector2d error = | |
| 1130 bounds_origin - focus_observer.focused_node_bounds_in_screen(); | |
| 1131 | |
| 1132 // Ideally, the length of the error vector should be 0.0f. But due to | |
| 1133 // potential rounding errors, we assume a larger limit (which is slightly | |
| 1134 // larger than square root of 2). | |
| 1135 EXPECT_LT(error.Length(), 1.4143f) | |
| 1136 << "Origin of bounds from focused node changed event is '" | |
| 1137 << focus_observer.focused_node_bounds_in_screen().ToString() | |
| 1138 << "' but AutofillClient is reporting '" << bounds_origin.ToString() | |
| 1139 << "'"; | |
| 1140 } | |
| OLD | NEW |