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 <stdint.h> 9 10 #include <memory> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 #include "base/macros.h" 16 #include "base/optional.h" 17 #include "base/test/task_environment.h" 18 #include "build/build_config.h" 19 #include "content/public/browser/render_frame_host.h" 20 #include "content/public/browser/render_view_host.h" 21 #include "content/public/test/browser_task_environment.h" 22 #include "content/public/test/browser_test_utils.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" 25 #include "third_party/blink/public/common/input/web_input_event.h" 26 #include "ui/base/page_transition_types.h" 27 28 #if defined(USE_AURA) 29 #include "ui/aura/test/aura_test_helper.h" 30 #endif 31 32 namespace aura { 33 namespace test { 34 class AuraTestHelper; 35 } 36 } // namespace aura 37 38 namespace blink { 39 namespace web_pref { 40 struct WebPreferences; 41 } 42 } // namespace blink 43 44 namespace display { 45 class Screen; 46 } 47 48 namespace net { 49 namespace test { 50 class MockNetworkChangeNotifier; 51 } 52 } // namespace net 53 54 namespace ui { 55 class ScopedOleInitializer; 56 } 57 58 namespace content { 59 60 class BrowserContext; 61 class ContentBrowserConsistencyChecker; 62 class MockRenderProcessHost; 63 class MockRenderProcessHostFactory; 64 class NavigationController; 65 class RenderProcessHostFactory; 66 class TestRenderFrameHostFactory; 67 class TestRenderViewHostFactory; 68 class TestRenderWidgetHostFactory; 69 class TestNavigationURLLoaderFactory; 70 class WebContents; 71 72 // An interface and utility for driving tests of RenderFrameHost. 73 class RenderFrameHostTester { 74 public: 75 enum class HeavyAdIssueType { 76 kNetworkTotal, 77 kCpuTotal, 78 kCpuPeak, 79 kAll, 80 }; 81 82 // Retrieves the RenderFrameHostTester that drives the specified 83 // RenderFrameHost. The RenderFrameHost must have been created while 84 // RenderFrameHost testing was enabled; use a 85 // RenderViewHostTestEnabler instance (see below) to do this. 86 static RenderFrameHostTester* For(RenderFrameHost* host); 87 88 // Calls the RenderFrameHost's private OnMessageReceived function with the 89 // given message. 90 static bool TestOnMessageReceived(RenderFrameHost* rfh, 91 const IPC::Message& msg); 92 93 // Commit the load pending in the given |controller| if any. 94 // TODO(ahemery): This should take a WebContents directly. 95 static void CommitPendingLoad(NavigationController* controller); 96 ~RenderFrameHostTester()97 virtual ~RenderFrameHostTester() {} 98 99 // Simulates initialization of the RenderFrame object in the renderer process 100 // and ensures internal state of RenderFrameHost is ready for simulating 101 // RenderFrame originated IPCs. 102 virtual void InitializeRenderFrameIfNeeded() = 0; 103 104 // Gives tests access to RenderFrameHostImpl::OnCreateChild. The returned 105 // RenderFrameHost is owned by the parent RenderFrameHost. 106 virtual RenderFrameHost* AppendChild(const std::string& frame_name) = 0; 107 108 // Same as AppendChild above, but simulates a custom allow attribute being 109 // used as the container policy. 110 virtual RenderFrameHost* AppendChildWithPolicy( 111 const std::string& frame_name, 112 const blink::ParsedFeaturePolicy& allow) = 0; 113 114 // Gives tests access to RenderFrameHostImpl::OnDetach. Destroys |this|. 115 virtual void Detach() = 0; 116 117 // Calls ProcessBeforeUnloadCompleted on this RenderFrameHost with the given 118 // parameter. 119 virtual void SimulateBeforeUnloadCompleted(bool proceed) = 0; 120 121 // Simulates the FrameHostMsg_Unload_ACK that fires if you commit a cross-site 122 // navigation without making any network requests. 123 virtual void SimulateUnloadACK() = 0; 124 125 // Set the feature policy header for the RenderFrameHost for test. Currently 126 // this is limited to setting an allowlist for a single feature. This function 127 // can be generalized as needed. Setting a header policy should only be done 128 // once per navigation of the RFH. 129 virtual void SimulateFeaturePolicyHeader( 130 blink::mojom::FeaturePolicyFeature feature, 131 const std::vector<url::Origin>& allowlist) = 0; 132 133 // Simulates the frame receiving a user activation. 134 virtual void SimulateUserActivation() = 0; 135 136 // Gets all the console messages requested via 137 // RenderFrameHost::AddMessageToConsole in this frame. 138 virtual const std::vector<std::string>& GetConsoleMessages() = 0; 139 140 // Get a count of the total number of heavy ad issues reported. 141 virtual int GetHeavyAdIssueCount(HeavyAdIssueType type) = 0; 142 }; 143 144 // An interface and utility for driving tests of RenderViewHost. 145 class RenderViewHostTester { 146 public: 147 // Retrieves the RenderViewHostTester that drives the specified 148 // RenderViewHost. The RenderViewHost must have been created while 149 // RenderViewHost testing was enabled; use a 150 // RenderViewHostTestEnabler instance (see below) to do this. 151 static RenderViewHostTester* For(RenderViewHost* host); 152 153 static void SimulateFirstPaint(RenderViewHost* rvh); 154 155 static std::unique_ptr<content::InputMsgWatcher> CreateInputWatcher( 156 RenderViewHost* rvh, 157 blink::WebInputEvent::Type type); 158 159 static void SendTouchEvent(RenderViewHost* rvh, 160 blink::SyntheticWebTouchEvent* touch_event); 161 ~RenderViewHostTester()162 virtual ~RenderViewHostTester() {} 163 164 // Gives tests access to RenderViewHostImpl::CreateRenderView. 165 virtual bool CreateTestRenderView( 166 const base::Optional<base::UnguessableToken>& opener_frame_route_id, 167 int proxy_routing_id, 168 bool created_with_opener) = 0; 169 170 // Makes the WasHidden/WasShown calls to the RenderWidget that 171 // tell it it has been hidden or restored from having been hidden. 172 virtual void SimulateWasHidden() = 0; 173 virtual void SimulateWasShown() = 0; 174 175 // Promote ComputeWebPreferences to public. 176 virtual blink::web_pref::WebPreferences TestComputeWebPreferences() = 0; 177 }; 178 179 // You can instantiate only one class like this at a time. During its 180 // lifetime, RenderViewHost and RenderFrameHost objects created may be used via 181 // RenderViewHostTester and RenderFrameHostTester respectively. 182 class RenderViewHostTestEnabler { 183 public: 184 RenderViewHostTestEnabler(); 185 ~RenderViewHostTestEnabler(); 186 187 private: 188 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestEnabler); 189 friend class RenderViewHostTestHarness; 190 191 #if defined(OS_ANDROID) 192 std::unique_ptr<display::Screen> screen_; 193 #endif 194 std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_; 195 std::unique_ptr<MockRenderProcessHostFactory> rph_factory_; 196 std::unique_ptr<TestRenderViewHostFactory> rvh_factory_; 197 std::unique_ptr<TestRenderFrameHostFactory> rfh_factory_; 198 std::unique_ptr<TestRenderWidgetHostFactory> rwhi_factory_; 199 std::unique_ptr<TestNavigationURLLoaderFactory> loader_factory_; 200 }; 201 202 // RenderViewHostTestHarness --------------------------------------------------- 203 class RenderViewHostTestHarness : public testing::Test { 204 public: 205 // Constructs a RenderViewHostTestHarness which uses |traits| to initialize 206 // its BrowserTaskEnvironment. 207 template <typename... TaskEnvironmentTraits> RenderViewHostTestHarness(TaskEnvironmentTraits &&...traits)208 explicit RenderViewHostTestHarness(TaskEnvironmentTraits&&... traits) 209 : RenderViewHostTestHarness(std::make_unique<BrowserTaskEnvironment>( 210 std::forward<TaskEnvironmentTraits>(traits)...)) {} 211 212 ~RenderViewHostTestHarness() override; 213 214 NavigationController& controller(); 215 216 // The contents under test. 217 WebContents* web_contents(); 218 219 // RVH/RFH getters are shorthand for oft-used bits of web_contents(). 220 221 // rvh() is equivalent to either of: 222 // web_contents()->GetMainFrame()->GetRenderViewHost() 223 // web_contents()->GetRenderViewHost() 224 RenderViewHost* rvh(); 225 226 // pending_rvh() is equivalent to: 227 // WebContentsTester::For(web_contents())->GetPendingRenderViewHost() 228 RenderViewHost* pending_rvh(); 229 230 // active_rvh() is equivalent to pending_rvh() ? pending_rvh() : rvh() 231 RenderViewHost* active_rvh(); 232 233 // main_rfh() is equivalent to web_contents()->GetMainFrame() 234 RenderFrameHost* main_rfh(); 235 236 // pending_main_rfh() is equivalent to: 237 // WebContentsTester::For(web_contents())->GetPendingMainFrame() 238 RenderFrameHost* pending_main_rfh(); 239 240 BrowserContext* browser_context(); 241 MockRenderProcessHost* process(); 242 243 // Frees the current WebContents for tests that want to test destruction. 244 void DeleteContents(); 245 246 // Sets the current WebContents for tests that want to alter it. Takes 247 // ownership of the WebContents passed. 248 void SetContents(std::unique_ptr<WebContents> contents); 249 250 // Creates a new test-enabled WebContents. Ownership passes to the 251 // caller. 252 std::unique_ptr<WebContents> CreateTestWebContents(); 253 254 // Cover for |contents()->NavigateAndCommit(url)|. See 255 // WebContentsTester::NavigateAndCommit for details. 256 // Optional parameter transition allows transition type to be controlled for 257 // greater flexibility for tests. 258 void NavigateAndCommit( 259 const GURL& url, 260 ui::PageTransition transition = ui::PAGE_TRANSITION_LINK); 261 262 // Sets the focused frame to the main frame of the WebContents for tests that 263 // rely on the focused frame not being null. 264 void FocusWebContentsOnMainFrame(); 265 266 protected: 267 // testing::Test 268 void SetUp() override; 269 void TearDown() override; 270 271 // Derived classes should override this method to use a custom BrowserContext. 272 // It is invoked by SetUp after threads were started. 273 // RenderViewHostTestHarness will take ownership of the returned 274 // BrowserContext. 275 virtual std::unique_ptr<BrowserContext> CreateBrowserContext(); 276 277 // Derived classes can override this method to have the test harness use a 278 // different BrowserContext than the one owned by this class. This is most 279 // useful for off-the-record contexts, which are usually owned by the original 280 // context. 281 virtual BrowserContext* GetBrowserContext(); 282 task_environment()283 BrowserTaskEnvironment* task_environment() { return task_environment_.get(); } 284 285 #if defined(USE_AURA) root_window()286 aura::Window* root_window() { return aura_test_helper_->GetContext(); } 287 #endif 288 289 // Replaces the RPH being used. 290 void SetRenderProcessHostFactory(RenderProcessHostFactory* factory); 291 292 private: 293 // The template constructor has to be in the header but it delegates to this 294 // constructor to initialize all other members out-of-line. 295 explicit RenderViewHostTestHarness( 296 std::unique_ptr<BrowserTaskEnvironment> task_environment); 297 298 std::unique_ptr<BrowserTaskEnvironment> task_environment_; 299 300 std::unique_ptr<ContentBrowserConsistencyChecker> consistency_checker_; 301 302 // TODO(crbug.com/1011275): This is a temporary work around to fix flakiness 303 // on tests. The default behavior of the network stack is to allocate a 304 // leaking SystemDnsConfigChangeNotifier. This holds on to a set of 305 // FilePathWatchers on Posix and ObjectWatchers on Windows that outlive 306 // the message queues of the task_environment_ and may post messages after 307 // their death. 308 std::unique_ptr<net::test::MockNetworkChangeNotifier> 309 network_change_notifier_; 310 311 std::unique_ptr<BrowserContext> browser_context_; 312 313 // This must be placed before |contents_| such that it will be destructed 314 // after it. See https://crbug.com/770451 315 std::unique_ptr<RenderViewHostTestEnabler> rvh_test_enabler_; 316 317 std::unique_ptr<WebContents> contents_; 318 #if defined(OS_WIN) 319 std::unique_ptr<ui::ScopedOleInitializer> ole_initializer_; 320 #endif 321 #if defined(USE_AURA) 322 std::unique_ptr<aura::test::AuraTestHelper> aura_test_helper_; 323 #endif 324 RenderProcessHostFactory* factory_ = nullptr; 325 326 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestHarness); 327 }; 328 329 } // namespace content 330 331 #endif // CONTENT_PUBLIC_TEST_TEST_RENDERER_HOST_H_ 332