cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / content / test / test_render_frame_host.cc
blob574ca8f417a0509f1ece377ab5e627f501075a55
1 // Copyright 2013 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.
5 #include "content/test/test_render_frame_host.h"
7 #include "base/command_line.h"
8 #include "content/browser/frame_host/frame_tree.h"
9 #include "content/browser/frame_host/navigation_handle_impl.h"
10 #include "content/browser/frame_host/navigation_request.h"
11 #include "content/browser/frame_host/navigator.h"
12 #include "content/browser/frame_host/navigator_impl.h"
13 #include "content/browser/frame_host/render_frame_host_delegate.h"
14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/common/frame_messages.h"
16 #include "content/public/browser/stream_handle.h"
17 #include "content/public/common/content_switches.h"
18 #include "content/public/common/url_constants.h"
19 #include "content/test/browser_side_navigation_test_utils.h"
20 #include "content/test/test_navigation_url_loader.h"
21 #include "content/test/test_render_view_host.h"
22 #include "net/base/load_flags.h"
23 #include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
24 #include "third_party/WebKit/public/web/WebSandboxFlags.h"
25 #include "third_party/WebKit/public/web/WebTreeScopeType.h"
26 #include "ui/base/page_transition_types.h"
28 namespace content {
30 TestRenderFrameHostCreationObserver::TestRenderFrameHostCreationObserver(
31 WebContents* web_contents)
32 : WebContentsObserver(web_contents), last_created_frame_(NULL) {
35 TestRenderFrameHostCreationObserver::~TestRenderFrameHostCreationObserver() {
38 void TestRenderFrameHostCreationObserver::RenderFrameCreated(
39 RenderFrameHost* render_frame_host) {
40 last_created_frame_ = render_frame_host;
43 TestRenderFrameHost::TestRenderFrameHost(SiteInstance* site_instance,
44 RenderViewHostImpl* render_view_host,
45 RenderFrameHostDelegate* delegate,
46 RenderWidgetHostDelegate* rwh_delegate,
47 FrameTree* frame_tree,
48 FrameTreeNode* frame_tree_node,
49 int32 routing_id,
50 int32 widget_routing_id,
51 int32 surface_id,
52 int flags)
53 : RenderFrameHostImpl(site_instance,
54 render_view_host,
55 delegate,
56 rwh_delegate,
57 frame_tree,
58 frame_tree_node,
59 routing_id,
60 widget_routing_id,
61 surface_id,
62 flags),
63 child_creation_observer_(delegate ? delegate->GetAsWebContents() : NULL),
64 contents_mime_type_("text/html"),
65 simulate_history_list_was_cleared_(false) {}
67 TestRenderFrameHost::~TestRenderFrameHost() {
70 TestRenderViewHost* TestRenderFrameHost::GetRenderViewHost() {
71 return static_cast<TestRenderViewHost*>(
72 RenderFrameHostImpl::GetRenderViewHost());
75 MockRenderProcessHost* TestRenderFrameHost::GetProcess() {
76 return static_cast<MockRenderProcessHost*>(RenderFrameHostImpl::GetProcess());
79 void TestRenderFrameHost::InitializeRenderFrameIfNeeded() {
80 if (!render_view_host()->IsRenderViewLive()) {
81 RenderViewHostTester::For(render_view_host())->CreateTestRenderView(
82 base::string16(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, -1, false);
86 TestRenderFrameHost* TestRenderFrameHost::AppendChild(
87 const std::string& frame_name) {
88 OnCreateChildFrame(GetProcess()->GetNextRoutingID(),
89 blink::WebTreeScopeType::Document, frame_name,
90 blink::WebSandboxFlags::None);
91 return static_cast<TestRenderFrameHost*>(
92 child_creation_observer_.last_created_frame());
95 void TestRenderFrameHost::SimulateNavigationStart(const GURL& url) {
96 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
97 switches::kEnableBrowserSideNavigation)) {
98 SendRendererInitiatedNavigationRequest(url, false);
99 return;
102 OnDidStartLoading(true);
103 OnDidStartProvisionalLoadForFrame(url);
106 void TestRenderFrameHost::SimulateRedirect(const GURL& new_url) {
107 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
108 switches::kEnableBrowserSideNavigation)) {
109 NavigationRequest* request = frame_tree_node_->navigation_request();
110 TestNavigationURLLoader* url_loader =
111 static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
112 CHECK(url_loader);
113 url_loader->SimulateServerRedirect(new_url);
114 return;
117 // Note that this does not simulate
118 // WebContentsImpl::DidGetRedirectForResourceRequest due to the difficulty in
119 // creating fake ResourceRequestDetails on the UI thread.
120 navigation_handle()->DidRedirectNavigation(new_url);
123 void TestRenderFrameHost::SimulateNavigationCommit(const GURL& url) {
124 if (frame_tree_node()->navigation_request())
125 PrepareForCommit();
127 FrameHostMsg_DidCommitProvisionalLoad_Params params;
128 params.page_id = ComputeNextPageID();
129 params.nav_entry_id = 0;
130 params.url = url;
131 params.transition = GetParent() ? ui::PAGE_TRANSITION_MANUAL_SUBFRAME
132 : ui::PAGE_TRANSITION_LINK;
133 params.should_update_history = true;
134 params.did_create_new_entry = true;
135 params.gesture = NavigationGestureUser;
136 params.contents_mime_type = contents_mime_type_;
137 params.is_post = false;
138 params.http_status_code = 200;
139 params.socket_address.set_host("2001:db8::1");
140 params.socket_address.set_port(80);
141 params.history_list_was_cleared = simulate_history_list_was_cleared_;
142 params.original_request_url = url;
144 url::Replacements<char> replacements;
145 replacements.ClearRef();
146 params.was_within_same_page =
147 url.ReplaceComponents(replacements) ==
148 GetLastCommittedURL().ReplaceComponents(replacements);
150 params.page_state = PageState::CreateForTesting(url, false, nullptr, nullptr);
152 SendNavigateWithParams(&params);
155 void TestRenderFrameHost::SimulateNavigationError(const GURL& url,
156 int error_code) {
157 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
158 switches::kEnableBrowserSideNavigation)) {
159 NavigationRequest* request = frame_tree_node_->navigation_request();
160 TestNavigationURLLoader* url_loader =
161 static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
162 CHECK(url_loader);
163 url_loader->SimulateError(error_code);
164 return;
167 FrameHostMsg_DidFailProvisionalLoadWithError_Params error_params;
168 error_params.error_code = error_code;
169 error_params.url = url;
170 OnDidFailProvisionalLoadWithError(error_params);
173 void TestRenderFrameHost::SimulateNavigationErrorPageCommit() {
174 CHECK(navigation_handle());
175 GURL error_url = GURL(kUnreachableWebDataURL);
176 OnDidStartProvisionalLoadForFrame(error_url);
177 FrameHostMsg_DidCommitProvisionalLoad_Params params;
178 params.page_id = ComputeNextPageID();
179 params.nav_entry_id = 0;
180 params.did_create_new_entry = true;
181 params.url = navigation_handle()->GetURL();
182 params.transition = GetParent() ? ui::PAGE_TRANSITION_MANUAL_SUBFRAME
183 : ui::PAGE_TRANSITION_LINK;
184 params.was_within_same_page = false;
185 params.url_is_unreachable = true;
186 params.page_state = PageState::CreateForTesting(navigation_handle()->GetURL(),
187 false, nullptr, nullptr);
188 SendNavigateWithParams(&params);
191 void TestRenderFrameHost::SimulateNavigationStop() {
192 if (is_loading()) {
193 OnDidStopLoading();
194 } else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
195 switches::kEnableBrowserSideNavigation)) {
196 // Even if the RenderFrameHost is not loading, there may still be an
197 // ongoing navigation in the FrameTreeNode. Cancel this one as well.
198 frame_tree_node()->ResetNavigationRequest(false);
202 void TestRenderFrameHost::SetContentsMimeType(const std::string& mime_type) {
203 contents_mime_type_ = mime_type;
206 void TestRenderFrameHost::SendBeforeUnloadACK(bool proceed) {
207 base::TimeTicks now = base::TimeTicks::Now();
208 OnBeforeUnloadACK(proceed, now, now);
211 void TestRenderFrameHost::SimulateSwapOutACK() {
212 OnSwappedOut();
215 void TestRenderFrameHost::SendNavigate(int page_id,
216 int nav_entry_id,
217 bool did_create_new_entry,
218 const GURL& url) {
219 SendNavigateWithParameters(page_id, nav_entry_id, did_create_new_entry, url,
220 ui::PAGE_TRANSITION_LINK, 200,
221 ModificationCallback());
224 void TestRenderFrameHost::SendFailedNavigate(int page_id,
225 int nav_entry_id,
226 bool did_create_new_entry,
227 const GURL& url) {
228 SendNavigateWithParameters(page_id, nav_entry_id, did_create_new_entry, url,
229 ui::PAGE_TRANSITION_RELOAD, 500,
230 ModificationCallback());
233 void TestRenderFrameHost::SendNavigateWithTransition(
234 int page_id,
235 int nav_entry_id,
236 bool did_create_new_entry,
237 const GURL& url,
238 ui::PageTransition transition) {
239 SendNavigateWithParameters(page_id, nav_entry_id, did_create_new_entry, url,
240 transition, 200, ModificationCallback());
243 void TestRenderFrameHost::SendNavigateWithModificationCallback(
244 int page_id,
245 int nav_entry_id,
246 bool did_create_new_entry,
247 const GURL& url,
248 const ModificationCallback& callback) {
249 SendNavigateWithParameters(page_id, nav_entry_id, did_create_new_entry, url,
250 ui::PAGE_TRANSITION_LINK, 200, callback);
253 void TestRenderFrameHost::SendNavigateWithParameters(
254 int page_id,
255 int nav_entry_id,
256 bool did_create_new_entry,
257 const GURL& url,
258 ui::PageTransition transition,
259 int response_code,
260 const ModificationCallback& callback) {
261 // DidStartProvisionalLoad may delete the pending entry that holds |url|,
262 // so we keep a copy of it to use below.
263 GURL url_copy(url);
264 OnDidStartLoading(true);
265 OnDidStartProvisionalLoadForFrame(url_copy);
267 FrameHostMsg_DidCommitProvisionalLoad_Params params;
268 params.page_id = page_id;
269 params.nav_entry_id = nav_entry_id;
270 params.url = url_copy;
271 params.transition = transition;
272 params.should_update_history = true;
273 params.did_create_new_entry = did_create_new_entry;
274 params.gesture = NavigationGestureUser;
275 params.contents_mime_type = contents_mime_type_;
276 params.is_post = false;
277 params.http_status_code = response_code;
278 params.socket_address.set_host("2001:db8::1");
279 params.socket_address.set_port(80);
280 params.history_list_was_cleared = simulate_history_list_was_cleared_;
281 params.original_request_url = url_copy;
283 url::Replacements<char> replacements;
284 replacements.ClearRef();
285 params.was_within_same_page =
286 transition != ui::PAGE_TRANSITION_RELOAD &&
287 transition != ui::PAGE_TRANSITION_TYPED &&
288 url_copy.ReplaceComponents(replacements) ==
289 GetLastCommittedURL().ReplaceComponents(replacements);
291 params.page_state =
292 PageState::CreateForTesting(url_copy, false, nullptr, nullptr);
294 if (!callback.is_null())
295 callback.Run(&params);
297 SendNavigateWithParams(&params);
300 void TestRenderFrameHost::SendNavigateWithParams(
301 FrameHostMsg_DidCommitProvisionalLoad_Params* params) {
302 FrameHostMsg_DidCommitProvisionalLoad msg(GetRoutingID(), *params);
303 OnDidCommitProvisionalLoad(msg);
306 void TestRenderFrameHost::NavigateAndCommitRendererInitiated(
307 int page_id,
308 bool did_create_new_entry,
309 const GURL& url) {
310 SendRendererInitiatedNavigationRequest(url, false);
311 // PlzNavigate: If no network request is needed by the navigation, then there
312 // will be no NavigationRequest, nor is it necessary to simulate the network
313 // stack commit.
314 if (frame_tree_node()->navigation_request())
315 PrepareForCommit();
316 bool browser_side_navigation =
317 base::CommandLine::ForCurrentProcess()->HasSwitch(
318 switches::kEnableBrowserSideNavigation);
319 CHECK_IMPLIES(browser_side_navigation, is_loading());
320 CHECK_IMPLIES(browser_side_navigation,
321 !frame_tree_node()->navigation_request());
322 SendNavigate(page_id, 0, did_create_new_entry, url);
325 void TestRenderFrameHost::SendRendererInitiatedNavigationRequest(
326 const GURL& url,
327 bool has_user_gesture) {
328 // Since this is renderer-initiated navigation, the RenderFrame must be
329 // initialized. Do it if it hasn't happened yet.
330 InitializeRenderFrameIfNeeded();
332 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
333 switches::kEnableBrowserSideNavigation)) {
334 BeginNavigationParams begin_params("GET", std::string(), net::LOAD_NORMAL,
335 has_user_gesture);
336 CommonNavigationParams common_params;
337 common_params.url = url;
338 common_params.referrer = Referrer(GURL(), blink::WebReferrerPolicyDefault);
339 common_params.transition = ui::PAGE_TRANSITION_LINK;
340 OnBeginNavigation(common_params, begin_params,
341 scoped_refptr<ResourceRequestBody>());
345 void TestRenderFrameHost::DidChangeOpener(int opener_routing_id) {
346 OnDidChangeOpener(opener_routing_id);
349 void TestRenderFrameHost::PrepareForCommit() {
350 PrepareForCommitWithServerRedirect(GURL());
353 void TestRenderFrameHost::PrepareForCommitWithServerRedirect(
354 const GURL& redirect_url) {
355 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
356 switches::kEnableBrowserSideNavigation)) {
357 // Non PlzNavigate
358 if (is_waiting_for_beforeunload_ack())
359 SendBeforeUnloadACK(true);
360 return;
363 // PlzNavigate
364 NavigationRequest* request = frame_tree_node_->navigation_request();
365 CHECK(request);
367 // Simulate a beforeUnload ACK from the renderer if the browser is waiting for
368 // it. If it runs it will update the request state.
369 if (request->state() == NavigationRequest::WAITING_FOR_RENDERER_RESPONSE)
370 SendBeforeUnloadACK(true);
372 CHECK(request->state() == NavigationRequest::STARTED);
374 TestNavigationURLLoader* url_loader =
375 static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
376 CHECK(url_loader);
378 // If a non-empty |redirect_url| was provided, simulate a server redirect.
379 if (!redirect_url.is_empty())
380 url_loader->SimulateServerRedirect(redirect_url);
382 // Simulate the network stack commit.
383 scoped_refptr<ResourceResponse> response(new ResourceResponse);
384 // TODO(carlosk): ideally with PlzNavigate it should be possible someday to
385 // fully commit the navigation at this call to CallOnResponseStarted.
386 url_loader->CallOnResponseStarted(response, MakeEmptyStream());
389 int32 TestRenderFrameHost::ComputeNextPageID() {
390 const NavigationEntryImpl* entry = static_cast<NavigationEntryImpl*>(
391 frame_tree_node()->navigator()->GetController()->GetPendingEntry());
392 DCHECK_IMPLIES(entry && entry->site_instance(),
393 entry->site_instance() == GetSiteInstance());
394 // Entry can be null when committing an error page (the pending entry was
395 // cleared during DidFailProvisionalLoad).
396 int page_id = entry ? entry->GetPageID() : -1;
397 if (page_id == -1) {
398 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(delegate());
399 page_id = web_contents->GetMaxPageIDForSiteInstance(GetSiteInstance()) + 1;
401 return page_id;
404 } // namespace content