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/common/page_transition_types.h"
13#include "content/public/test/test_browser_thread_bundle.h"
14#include "testing/gtest/include/gtest/gtest.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 RenderViewHost.
43class RenderViewHostTester {
44 public:
45  // Retrieves the RenderViewHostTester that drives the specified
46  // RenderViewHost.  The RenderViewHost must have been created while
47  // RenderViewHost testing was enabled; use a
48  // RenderViewHostTestEnabler instance (see below) to do this.
49  static RenderViewHostTester* For(RenderViewHost* host);
50
51  // If the given WebContentsImpl has a pending RVH, returns it, otherwise NULL.
52  static RenderViewHost* GetPendingForController(
53      NavigationController* controller);
54
55  // This removes the need to expose
56  // RenderViewHostImpl::is_swapped_out() outside of content.
57  //
58  // This is safe to call on any RenderViewHost, not just ones
59  // constructed while a RenderViewHostTestEnabler is in play.
60  static bool IsRenderViewHostSwappedOut(RenderViewHost* rvh);
61
62  // Calls the RenderViewHosts' private OnMessageReceived function with the
63  // given message.
64  static bool TestOnMessageReceived(RenderViewHost* rvh,
65                                    const IPC::Message& msg);
66
67  // Returns whether the underlying web-page has any touch-event handlers.
68  static bool HasTouchEventHandler(RenderViewHost* rvh);
69
70  virtual ~RenderViewHostTester() {}
71
72  // Gives tests access to RenderViewHostImpl::CreateRenderView.
73  virtual bool CreateRenderView(const base::string16& frame_name,
74                                int opener_route_id,
75                                int32 max_page_id) = 0;
76
77  // Calls OnMsgNavigate on the RenderViewHost with the given information,
78  // setting the rest of the parameters in the message to the "typical" values.
79  // This is a helper function for simulating the most common types of loads.
80  virtual void SendNavigate(int page_id, const GURL& url) = 0;
81  virtual void SendFailedNavigate(int page_id, const GURL& url) = 0;
82
83  // Calls OnMsgNavigate on the RenderViewHost with the given information,
84  // including a custom PageTransition.  Sets the rest of the
85  // parameters in the message to the "typical" values. This is a helper
86  // function for simulating the most common types of loads.
87  virtual void SendNavigateWithTransition(int page_id, const GURL& url,
88                                          PageTransition transition) = 0;
89
90  // Calls OnMsgShouldCloseACK on the RenderViewHost with the given parameter.
91  virtual void SendShouldCloseACK(bool proceed) = 0;
92
93  // If set, future loads will have |mime_type| set as the mime type.
94  // If not set, the mime type will default to "text/html".
95  virtual void SetContentsMimeType(const std::string& mime_type) = 0;
96
97  // Simulates the SwapOut_ACK that fires if you commit a cross-site
98  // navigation without making any network requests.
99  virtual void SimulateSwapOutACK() = 0;
100
101  // Makes the WasHidden/WasShown calls to the RenderWidget that
102  // tell it it has been hidden or restored from having been hidden.
103  virtual void SimulateWasHidden() = 0;
104  virtual void SimulateWasShown() = 0;
105};
106
107// You can instantiate only one class like this at a time.  During its
108// lifetime, RenderViewHost objects created may be used via
109// RenderViewHostTester.
110class RenderViewHostTestEnabler {
111 public:
112  RenderViewHostTestEnabler();
113  ~RenderViewHostTestEnabler();
114
115 private:
116  DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestEnabler);
117  friend class RenderViewHostTestHarness;
118
119  scoped_ptr<MockRenderProcessHostFactory> rph_factory_;
120  scoped_ptr<TestRenderViewHostFactory> rvh_factory_;
121  scoped_ptr<TestRenderFrameHostFactory> rfh_factory_;
122};
123
124// RenderViewHostTestHarness ---------------------------------------------------
125class RenderViewHostTestHarness : public testing::Test {
126 public:
127  RenderViewHostTestHarness();
128  virtual ~RenderViewHostTestHarness();
129
130  NavigationController& controller();
131  WebContents* web_contents();
132  RenderViewHost* rvh();
133  RenderViewHost* pending_rvh();
134  RenderViewHost* active_rvh();
135  RenderFrameHost* main_rfh();
136  BrowserContext* browser_context();
137  MockRenderProcessHost* process();
138
139  // Frees the current WebContents for tests that want to test destruction.
140  void DeleteContents();
141
142  // Sets the current WebContents for tests that want to alter it. Takes
143  // ownership of the WebContents passed.
144  void SetContents(WebContents* contents);
145
146  // Creates a new test-enabled WebContents. Ownership passes to the
147  // caller.
148  WebContents* CreateTestWebContents();
149
150  // Cover for |contents()->NavigateAndCommit(url)|. See
151  // WebContentsTester::NavigateAndCommit for details.
152  void NavigateAndCommit(const GURL& url);
153
154  // Simulates a reload of the current page.
155  void Reload();
156  void FailedReload();
157
158 protected:
159  // testing::Test
160  virtual void SetUp() OVERRIDE;
161  virtual void TearDown() OVERRIDE;
162
163  // Derived classes should override this method to use a custom BrowserContext.
164  // It is invoked by SetUp after threads were started.
165  // RenderViewHostTestHarness will take ownership of the returned
166  // BrowserContext.
167  virtual BrowserContext* CreateBrowserContext();
168
169  // Configures which TestBrowserThreads inside |thread_bundle| are backed by
170  // real threads. Must be called before SetUp().
171  void SetThreadBundleOptions(int options) {
172    DCHECK(thread_bundle_.get() == NULL);
173    thread_bundle_options_ = options;
174  }
175
176  TestBrowserThreadBundle* thread_bundle() { return thread_bundle_.get(); }
177
178#if defined(USE_AURA)
179  aura::Window* root_window() { return aura_test_helper_->root_window(); }
180#endif
181
182  // Replaces the RPH being used.
183  void SetRenderProcessHostFactory(RenderProcessHostFactory* factory);
184
185 private:
186  scoped_ptr<BrowserContext> browser_context_;
187
188  // It is important not to use this directly in the implementation as
189  // web_contents() and SetContents() are virtual and may be
190  // overridden by subclasses.
191  scoped_ptr<WebContents> contents_;
192#if defined(OS_WIN)
193  scoped_ptr<ui::ScopedOleInitializer> ole_initializer_;
194#endif
195#if defined(USE_AURA)
196  scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
197#endif
198  RenderViewHostTestEnabler rvh_test_enabler_;
199
200  int thread_bundle_options_;
201  scoped_ptr<TestBrowserThreadBundle> thread_bundle_;
202
203  DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestHarness);
204};
205
206}  // namespace content
207
208#endif  // CONTENT_PUBLIC_TEST_TEST_RENDERER_HOST_H_
209