1// Copyright (c) 2012 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#ifndef CONTENT_PUBLIC_TEST_TEST_RENDERER_HOST_H_
6#define CONTENT_PUBLIC_TEST_TEST_RENDERER_HOST_H_
7
8#include "base/memory/scoped_ptr.h"
9#include "base/message_loop/message_loop.h"
10#include "content/public/browser/render_frame_host.h"
11#include "content/public/browser/render_view_host.h"
12#include "content/public/test/test_browser_thread_bundle.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "ui/base/page_transition_types.h"
15
16#if defined(USE_AURA)
17#include "ui/aura/test/aura_test_helper.h"
18#endif
19
20namespace aura {
21namespace test {
22class AuraTestHelper;
23}
24}
25
26namespace ui {
27class ScopedOleInitializer;
28}
29
30namespace content {
31
32class BrowserContext;
33class MockRenderProcessHost;
34class MockRenderProcessHostFactory;
35class NavigationController;
36class RenderProcessHostFactory;
37class RenderViewHostDelegate;
38class TestRenderFrameHostFactory;
39class TestRenderViewHostFactory;
40class WebContents;
41
42// An interface and utility for driving tests of RenderFrameHost.
43class RenderFrameHostTester {
44 public:
45  // Retrieves the RenderFrameHostTester that drives the specified
46  // RenderFrameHost. The RenderFrameHost must have been created while
47  // RenderFrameHost testing was enabled; use a
48  // RenderViewHostTestEnabler instance (see below) to do this.
49  static RenderFrameHostTester* For(RenderFrameHost* host);
50
51  virtual ~RenderFrameHostTester() {}
52
53  // Gives tests access to RenderFrameHostImpl::OnCreateChild. The returned
54  // RenderFrameHost is owned by the parent RenderFrameHost.
55  virtual RenderFrameHost* AppendChild(const std::string& frame_name) = 0;
56
57  // Calls OnMsgNavigate on the RenderViewHost with the given information,
58  // including a custom PageTransition.  Sets the rest of the
59  // parameters in the message to the "typical" values. This is a helper
60  // function for simulating the most common types of loads.
61  virtual void SendNavigateWithTransition(int page_id,
62                                          const GURL& url,
63                                          ui::PageTransition transition) = 0;
64};
65
66// An interface and utility for driving tests of RenderViewHost.
67class RenderViewHostTester {
68 public:
69  // Retrieves the RenderViewHostTester that drives the specified
70  // RenderViewHost.  The RenderViewHost must have been created while
71  // RenderViewHost testing was enabled; use a
72  // RenderViewHostTestEnabler instance (see below) to do this.
73  static RenderViewHostTester* For(RenderViewHost* host);
74
75  // If the given WebContentsImpl has a pending RVH, returns it, otherwise NULL.
76  static RenderViewHost* GetPendingForController(
77      NavigationController* controller);
78
79  // This removes the need to expose
80  // RenderViewHostImpl::is_swapped_out() outside of content.
81  //
82  // This is safe to call on any RenderViewHost, not just ones
83  // constructed while a RenderViewHostTestEnabler is in play.
84  static bool IsRenderViewHostSwappedOut(RenderViewHost* rvh);
85
86  // Calls the RenderViewHosts' private OnMessageReceived function with the
87  // given message.
88  static bool TestOnMessageReceived(RenderViewHost* rvh,
89                                    const IPC::Message& msg);
90
91  // Returns whether the underlying web-page has any touch-event handlers.
92  static bool HasTouchEventHandler(RenderViewHost* rvh);
93
94  virtual ~RenderViewHostTester() {}
95
96  // Gives tests access to RenderViewHostImpl::CreateRenderView.
97  virtual bool CreateRenderView(const base::string16& frame_name,
98                                int opener_route_id,
99                                int proxy_routing_id,
100                                int32 max_page_id,
101                                bool created_with_opener) = 0;
102
103  // Calls OnMsgNavigate on the RenderViewHost with the given information,
104  // setting the rest of the parameters in the message to the "typical" values.
105  // This is a helper function for simulating the most common types of loads.
106  virtual void SendNavigate(int page_id, const GURL& url) = 0;
107  virtual void SendFailedNavigate(int page_id, const GURL& url) = 0;
108
109  // Calls OnMsgNavigate on the RenderViewHost with the given information,
110  // including a custom PageTransition.  Sets the rest of the
111  // parameters in the message to the "typical" values. This is a helper
112  // function for simulating the most common types of loads.
113  virtual void SendNavigateWithTransition(int page_id, const GURL& url,
114                                          ui::PageTransition transition) = 0;
115
116  // Calls OnBeforeUnloadACK on the main RenderFrameHost with the given
117  // parameter.
118  virtual void SendBeforeUnloadACK(bool proceed) = 0;
119
120  // If set, future loads will have |mime_type| set as the mime type.
121  // If not set, the mime type will default to "text/html".
122  virtual void SetContentsMimeType(const std::string& mime_type) = 0;
123
124  // Simulates the SwapOut_ACK that fires if you commit a cross-site
125  // navigation without making any network requests.
126  virtual void SimulateSwapOutACK() = 0;
127
128  // Makes the WasHidden/WasShown calls to the RenderWidget that
129  // tell it it has been hidden or restored from having been hidden.
130  virtual void SimulateWasHidden() = 0;
131  virtual void SimulateWasShown() = 0;
132};
133
134// You can instantiate only one class like this at a time.  During its
135// lifetime, RenderViewHost and RenderFrameHost objects created may be used via
136// RenderViewHostTester and RenderFrameHostTester respectively.
137class RenderViewHostTestEnabler {
138 public:
139  RenderViewHostTestEnabler();
140  ~RenderViewHostTestEnabler();
141
142 private:
143  DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestEnabler);
144  friend class RenderViewHostTestHarness;
145
146  scoped_ptr<MockRenderProcessHostFactory> rph_factory_;
147  scoped_ptr<TestRenderViewHostFactory> rvh_factory_;
148  scoped_ptr<TestRenderFrameHostFactory> rfh_factory_;
149};
150
151// RenderViewHostTestHarness ---------------------------------------------------
152class RenderViewHostTestHarness : public testing::Test {
153 public:
154  RenderViewHostTestHarness();
155  virtual ~RenderViewHostTestHarness();
156
157  NavigationController& controller();
158
159  // The contents under test.
160  WebContents* web_contents();
161
162  // RVH/RFH getters are shorthand for oft-used bits of web_contents().
163
164  // rvh() is equivalent to either of:
165  //   web_contents()->GetMainFrame()->GetRenderViewHost()
166  //   web_contents()->GetRenderViewHost()
167  RenderViewHost* rvh();
168
169  // pending_rvh() is equivalent to:
170  //   WebContentsTester::For(web_contents())->GetPendingRenderViewHost()
171  RenderViewHost* pending_rvh();
172
173  // active_rvh() is equivalent to pending_rvh() ? pending_rvh() : rvh()
174  RenderViewHost* active_rvh();
175
176  // main_rfh() is equivalent to web_contents()->GetMainFrame()
177  RenderFrameHost* main_rfh();
178
179  // pending_main_rfh() is equivalent to:
180  //   WebContentsTester::For(web_contents())->GetPendingMainFrame()
181  RenderFrameHost* pending_main_rfh();
182
183  BrowserContext* browser_context();
184  MockRenderProcessHost* process();
185
186  // Frees the current WebContents for tests that want to test destruction.
187  void DeleteContents();
188
189  // Sets the current WebContents for tests that want to alter it. Takes
190  // ownership of the WebContents passed.
191  void SetContents(WebContents* contents);
192
193  // Creates a new test-enabled WebContents. Ownership passes to the
194  // caller.
195  WebContents* CreateTestWebContents();
196
197  // Cover for |contents()->NavigateAndCommit(url)|. See
198  // WebContentsTester::NavigateAndCommit for details.
199  void NavigateAndCommit(const GURL& url);
200
201  // Simulates a reload of the current page.
202  void Reload();
203  void FailedReload();
204
205 protected:
206  // testing::Test
207  virtual void SetUp() OVERRIDE;
208  virtual void TearDown() OVERRIDE;
209
210  // Derived classes should override this method to use a custom BrowserContext.
211  // It is invoked by SetUp after threads were started.
212  // RenderViewHostTestHarness will take ownership of the returned
213  // BrowserContext.
214  virtual BrowserContext* CreateBrowserContext();
215
216  // Configures which TestBrowserThreads inside |thread_bundle| are backed by
217  // real threads. Must be called before SetUp().
218  void SetThreadBundleOptions(int options) {
219    DCHECK(thread_bundle_.get() == NULL);
220    thread_bundle_options_ = options;
221  }
222
223  TestBrowserThreadBundle* thread_bundle() { return thread_bundle_.get(); }
224
225#if defined(USE_AURA)
226  aura::Window* root_window() { return aura_test_helper_->root_window(); }
227#endif
228
229  // Replaces the RPH being used.
230  void SetRenderProcessHostFactory(RenderProcessHostFactory* factory);
231
232 private:
233  scoped_ptr<BrowserContext> browser_context_;
234
235  scoped_ptr<WebContents> contents_;
236#if defined(OS_WIN)
237  scoped_ptr<ui::ScopedOleInitializer> ole_initializer_;
238#endif
239#if defined(USE_AURA)
240  scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
241#endif
242  RenderViewHostTestEnabler rvh_test_enabler_;
243
244  int thread_bundle_options_;
245  scoped_ptr<TestBrowserThreadBundle> thread_bundle_;
246
247  DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestHarness);
248};
249
250}  // namespace content
251
252#endif  // CONTENT_PUBLIC_TEST_TEST_RENDERER_HOST_H_
253