OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include <vector> | |
6 | |
7 #include "content/browser/frame_host/frame_tree_node.h" | |
8 #include "content/browser/frame_host/render_frame_host_impl.h" | |
9 #include "content/browser/web_contents/web_contents_impl.h" | |
10 #include "content/public/browser/host_zoom_map.h" | |
11 #include "content/public/browser/navigation_entry.h" | |
12 #include "content/public/common/page_zoom.h" | |
13 #include "content/public/test/browser_test_utils.h" | |
14 #include "content/public/test/content_browser_test.h" | |
15 #include "content/public/test/content_browser_test_utils.h" | |
16 #include "content/shell/browser/shell.h" | |
17 #include "content/test/content_browser_test_utils_internal.h" | |
18 #include "net/dns/mock_host_resolver.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 #include "url/gurl.h" | |
21 | |
22 namespace content { | |
23 | |
24 class IFrameZoomBrowserTest : public ContentBrowserTest { | |
25 public: | |
26 IFrameZoomBrowserTest() {} | |
27 | |
28 protected: | |
29 void SetUpOnMainThread() override { | |
30 host_resolver()->AddRule("*", "127.0.0.1"); | |
31 ASSERT_TRUE(embedded_test_server()->Start()); | |
32 SetupCrossSiteRedirector(embedded_test_server()); | |
33 } | |
34 | |
35 WebContentsImpl* web_contents() { | |
36 return static_cast<WebContentsImpl*>(shell()->web_contents()); | |
37 } | |
38 }; | |
39 | |
40 double GetMainframeWindowBorder(const ToRenderFrameHost& adapter) { | |
41 double border; | |
42 const char kGetMainframeBorder[] = "window.domAutomationController.send(" | |
43 "window.outerWidth - window.innerWidth" | |
44 ");"; | |
45 EXPECT_TRUE( | |
46 ExecuteScriptAndExtractDouble(adapter, kGetMainframeBorder, &border)); | |
47 return border; | |
48 } | |
49 | |
50 double GetMainframeZoomFactor(const ToRenderFrameHost& adapter, double border) { | |
51 const char kGetMainframeZoomLevel[] = | |
52 "window.domAutomationController.send(" | |
53 "(window.outerWidth - %f)/window.innerWidth" | |
54 ");"; | |
55 double zoom_factor; | |
56 EXPECT_TRUE(ExecuteScriptAndExtractDouble( | |
57 adapter, base::StringPrintf(kGetMainframeZoomLevel, border), | |
58 &zoom_factor)); | |
59 return zoom_factor; | |
60 } | |
61 | |
62 double GetSubframeWidth(const ToRenderFrameHost& adapter) { | |
63 double width; | |
64 EXPECT_TRUE(ExecuteScriptAndExtractDouble( | |
65 adapter, "window.domAutomationController.send(window.innerWidth);", | |
66 &width)); | |
67 return width; | |
68 } | |
69 | |
70 #define SETUP_A_B_A_NESTED_FRAMES() \ | |
71 std::string top_level_host("a.com"); \ | |
72 GURL main_url(embedded_test_server()->GetURL( \ | |
73 top_level_host, "/cross_site_iframe_factory.html?a(b(a))")); \ | |
74 EXPECT_TRUE(NavigateToURL(shell(), main_url)); \ | |
75 NavigationEntry* entry = \ | |
76 web_contents()->GetController().GetLastCommittedEntry(); \ | |
77 ASSERT_TRUE(entry); \ | |
78 GURL loaded_url = HostZoomMap::GetURLFromEntry(entry); \ | |
79 EXPECT_EQ(top_level_host, loaded_url.host()); \ | |
80 \ | |
81 FrameTreeNode* root = \ | |
82 static_cast<WebContentsImpl*>(web_contents())->GetFrameTree()->root(); \ | |
83 auto subframe1 = root->child_at(0)->current_frame_host(); \ | |
alexmos
2016/04/21 17:35:35
I'd spell out the RenderFrameHost* type for better
alexmos
2016/04/21 17:35:35
"child" and "grandchild" might be better names, si
wjmaclean
2016/04/22 19:57:01
Done & Done.
| |
84 auto subframe2 = root->child_at(0)->child_at(0)->current_frame_host(); \ | |
alexmos
2016/04/21 17:35:35
nit: subframe1->child_at(0)->current_frame_host()
wjmaclean
2016/04/22 19:57:01
subframe1 is a RenderFrameHostImpl*, so this doesn
alexmos
2016/04/25 22:43:27
Acknowledged. I'm too used to these kinds of thin
| |
85 \ | |
86 /* The following calls must be made when the page's scale factor = 1.0.*/ \ | |
87 double scale_one_subframe1_width = GetSubframeWidth(subframe1); \ | |
88 double scale_one_subframe2_width = GetSubframeWidth(subframe2); \ | |
89 double main_frame_window_border = GetMainframeWindowBorder(web_contents()); \ | |
90 \ | |
91 HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(web_contents()); \ | |
92 double default_zoom_level = host_zoom_map->GetDefaultZoomLevel(); \ | |
93 EXPECT_EQ(0.0, default_zoom_level); \ | |
94 \ | |
95 EXPECT_DOUBLE_EQ(1.0, GetMainframeZoomFactor(web_contents(), \ | |
96 main_frame_window_border)); | |
97 | |
98 struct FrameResizeObserver { | |
99 FrameResizeObserver(RenderFrameHost* adapter, | |
alexmos
2016/04/21 17:35:35
nit: rename adapter to host or frame or similar.
wjmaclean
2016/04/22 19:57:01
Done.
| |
100 std::string label, | |
101 double inner_width, | |
102 double tol) | |
alexmos
2016/04/21 17:35:35
nit: s/tol/tolerance/
wjmaclean
2016/04/22 19:57:01
Done.
| |
103 : frame_adapter(adapter), | |
104 msg_label(std::move(label)), | |
105 resized(false), | |
106 expected_inner_width(inner_width), | |
107 tolerance(tol) { | |
108 SetupOnResizeCallback(adapter, msg_label); | |
109 } | |
110 | |
111 void SetupOnResizeCallback(const ToRenderFrameHost& adapter, | |
112 const std::string& label) { | |
113 const char kOnResizeCallbackSetup[] = | |
114 "document.body.onresize = function(){" | |
115 " window.domAutomationController.setAutomationId(0);" | |
116 " window.domAutomationController.send('%s ' + window.innerWidth);" | |
117 "};"; | |
118 EXPECT_TRUE(ExecuteScript( | |
119 adapter, base::StringPrintf(kOnResizeCallbackSetup, label.c_str()))); | |
120 } | |
121 | |
122 void Check(const std::string& status_msg) { | |
123 if (status_msg.find(msg_label) != 0) | |
124 return; | |
125 | |
126 double inner_width = std::stod(status_msg.substr(msg_label.length() + 1)); | |
127 resized = std::abs(expected_inner_width - inner_width) < tolerance; | |
alexmos
2016/04/21 17:35:35
So this won't check whether the subframes zoomed t
wjmaclean
2016/04/21 17:59:35
I think you've got it backwards: this method allow
alexmos
2016/04/21 19:02:40
Ah, I see. Thanks for clarifying! (Let's explain
alexmos
2016/04/21 19:08:45
Also, maybe rename |resized| to |zoomed_correctly|
wjmaclean
2016/04/22 19:57:01
It *seems* like it always fires ... but I can't po
alexmos
2016/04/25 22:43:27
Acknowledged. It might be good to document the fa
| |
128 } | |
129 | |
130 FrameResizeObserver* toThis() {return this;} | |
131 | |
132 RenderFrameHost* frame_adapter; | |
133 std::string msg_label; | |
134 bool resized; | |
135 double expected_inner_width; | |
136 double tolerance; | |
137 }; | |
138 | |
139 void WaitAndCheckFrameResize( | |
140 DOMMessageQueue& msg_queue, | |
141 std::vector<FrameResizeObserver>& frame_observers) { | |
142 std::string status; | |
143 while (msg_queue.WaitForMessage(&status)) { | |
144 // Strip the double quotes from the message. | |
145 status = status.substr(1, status.length() -2); | |
146 | |
147 bool all_resized = true; | |
148 | |
149 // Use auto& to operate on a reference, and not a copy. | |
150 for (auto& observer : frame_observers) { | |
151 observer.Check(status); | |
152 all_resized = all_resized && observer.resized; | |
153 } | |
154 | |
155 if (all_resized) | |
156 break; | |
157 } | |
158 } | |
159 | |
160 IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, SubframesZoomProperly) { | |
161 SETUP_A_B_A_NESTED_FRAMES(); | |
162 | |
163 const double new_zoom_factor = 2.5; | |
164 { | |
165 DOMMessageQueue msg_queue; | |
166 | |
167 const double kTolerance = 0.1; | |
168 std::vector<FrameResizeObserver> frame_observers; | |
169 frame_observers.emplace_back(subframe1, "subframe1", | |
170 scale_one_subframe1_width, kTolerance); | |
171 frame_observers.emplace_back(subframe2, "subframe2", | |
172 scale_one_subframe2_width, kTolerance); | |
173 | |
174 const double new_zoom_level = | |
175 default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor); | |
176 host_zoom_map->SetZoomLevelForHost(top_level_host, new_zoom_level); | |
177 | |
178 WaitAndCheckFrameResize(msg_queue, frame_observers); | |
179 } | |
180 | |
181 EXPECT_DOUBLE_EQ( | |
182 new_zoom_factor, | |
183 GetMainframeZoomFactor(web_contents(), main_frame_window_border)); | |
184 } | |
185 | |
186 IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, SubframesDontZoomIndependently) { | |
187 SETUP_A_B_A_NESTED_FRAMES(); | |
188 | |
189 const double new_zoom_factor = 2.0; | |
190 const double new_zoom_level = | |
191 default_zoom_level + ZoomFactorToZoomLevel(new_zoom_factor); | |
192 | |
193 // This should not cause the nested iframe to change its zoom. | |
194 host_zoom_map->SetZoomLevelForHost("b.com", new_zoom_level); | |
195 | |
196 EXPECT_DOUBLE_EQ( | |
197 1.0, GetMainframeZoomFactor(web_contents(), main_frame_window_border)); | |
198 EXPECT_EQ(scale_one_subframe1_width, GetSubframeWidth(subframe1)); | |
199 EXPECT_EQ(scale_one_subframe2_width, GetSubframeWidth(subframe2)); | |
200 | |
201 // When we navigate so that b.com is the top-level site, then it has the | |
202 // expected zoom. | |
203 EXPECT_TRUE(NavigateToURL( | |
204 shell(), embedded_test_server()->GetURL( | |
205 "b.com", "/cross_site_iframe_factory.html?b"))); | |
206 EXPECT_DOUBLE_EQ( | |
207 new_zoom_factor, | |
208 GetMainframeZoomFactor(web_contents(), main_frame_window_border)); | |
209 } | |
210 | |
211 IN_PROC_BROWSER_TEST_F(IFrameZoomBrowserTest, AllFramesGetDefaultZoom) { | |
212 SETUP_A_B_A_NESTED_FRAMES(); | |
213 | |
214 const double new_default_zoom_factor = 2.0; | |
215 { | |
216 DOMMessageQueue msg_queue; | |
217 | |
218 const double kTolerance = 0.1; | |
219 std::vector<FrameResizeObserver> frame_observers; | |
220 frame_observers.emplace_back(subframe1, "subframe1", | |
221 scale_one_subframe1_width, kTolerance); | |
222 frame_observers.emplace_back(subframe2, "subframe2", | |
223 scale_one_subframe2_width, kTolerance); | |
224 | |
225 const double new_default_zoom_level = | |
226 default_zoom_level + ZoomFactorToZoomLevel(new_default_zoom_factor); | |
227 | |
228 host_zoom_map->SetZoomLevelForHost("b.com", new_default_zoom_level + 1.0); | |
229 host_zoom_map->SetDefaultZoomLevel(new_default_zoom_level); | |
230 | |
231 WaitAndCheckFrameResize(msg_queue, frame_observers); | |
232 } | |
233 EXPECT_DOUBLE_EQ( | |
234 new_default_zoom_factor, | |
235 GetMainframeZoomFactor(web_contents(), main_frame_window_border)); | |
236 } | |
alexmos
2016/04/21 17:35:35
So far, these are are about A-B-A without subframe
wjmaclean
2016/04/21 17:59:35
I'm ok with adding some tests to test subframe nav
| |
237 | |
238 } // namespace content | |
OLD | NEW |