blob: 878dac42bf3d876019fb394f58a19fc8faf6bd2a [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/page_transition_types.h"
#if defined(USE_AURA)
#include "ui/aura/test/aura_test_helper.h"
namespace aura {
namespace test {
class AuraTestHelper;
namespace display {
class Screen;
namespace net {
class NetworkChangeNotifier;
namespace ui {
class InputDeviceManager;
class ScopedOleInitializer;
namespace content {
class BrowserContext;
class ContentBrowserSanityChecker;
class MockRenderProcessHost;
class MockRenderProcessHostFactory;
class NavigationController;
class RenderProcessHostFactory;
class TestRenderFrameHostFactory;
class TestRenderViewHostFactory;
class TestRenderWidgetHostFactory;
class WebContents;
struct WebPreferences;
// An interface and utility for driving tests of RenderFrameHost.
class RenderFrameHostTester {
// Retrieves the RenderFrameHostTester that drives the specified
// RenderFrameHost. The RenderFrameHost must have been created while
// RenderFrameHost testing was enabled; use a
// RenderViewHostTestEnabler instance (see below) to do this.
static RenderFrameHostTester* For(RenderFrameHost* host);
// Calls the RenderFrameHost's private OnMessageReceived function with the
// given message.
static bool TestOnMessageReceived(RenderFrameHost* rfh,
const IPC::Message& msg);
// Commit the load pending in the given |controller| if any.
// TODO(ahemery): This should take a WebContents directly.
static void CommitPendingLoad(NavigationController* controller);
virtual ~RenderFrameHostTester() {}
// Simulates initialization of the RenderFrame object in the renderer process
// and ensures internal state of RenderFrameHost is ready for simulating
// RenderFrame originated IPCs.
virtual void InitializeRenderFrameIfNeeded() = 0;
// Gives tests access to RenderFrameHostImpl::OnCreateChild. The returned
// RenderFrameHost is owned by the parent RenderFrameHost.
virtual RenderFrameHost* AppendChild(const std::string& frame_name) = 0;
// Gives tests access to RenderFrameHostImpl::OnDetach. Destroys |this|.
virtual void Detach() = 0;
// Simulates a navigation stopping in the RenderFrameHost.
virtual void SimulateNavigationStop() = 0;
// Calls DidCommitProvisionalLoad on the RenderFrameHost with the given
// information with various sets of parameters. These are helper functions for
// simulating the most common types of loads.
// Guidance for calling this:
// - nav_entry_id should be 0 if simulating a renderer-initiated navigation;
// if simulating a browser-initiated one, pass the GetUniqueID() value of
// the NavigationController's PendingEntry.
// - did_create_new_entry should be true if simulating a navigation that
// created a new navigation entry; false for history navigations, reloads,
// and other navigations that don't affect the history list.
virtual void SendNavigateWithTransition(int nav_entry_id,
bool did_create_new_entry,
const GURL& url,
ui::PageTransition transition) = 0;
// Calls OnBeforeUnloadACK on this RenderFrameHost with the given parameter.
virtual void SendBeforeUnloadACK(bool proceed) = 0;
// Simulates the SwapOut_ACK that fires if you commit a cross-site
// navigation without making any network requests.
virtual void SimulateSwapOutACK() = 0;
// Set the feature policy header for the RenderFrameHost for test. Currently
// this is limited to setting a whitelist for a single feature. This function
// can be generalized as needed. Setting a header policy should only be done
// once per navigation of the RFH.
virtual void SimulateFeaturePolicyHeader(
blink::mojom::FeaturePolicyFeature feature,
const std::vector<url::Origin>& whitelist) = 0;
// Gets all the console messages requested via
// RenderFrameHost::AddMessageToConsole in this frame.
virtual const std::vector<std::string>& GetConsoleMessages() = 0;
// An interface and utility for driving tests of RenderViewHost.
class RenderViewHostTester {
// Retrieves the RenderViewHostTester that drives the specified
// RenderViewHost. The RenderViewHost must have been created while
// RenderViewHost testing was enabled; use a
// RenderViewHostTestEnabler instance (see below) to do this.
static RenderViewHostTester* For(RenderViewHost* host);
static void SimulateFirstPaint(RenderViewHost* rvh);
// Returns whether the underlying web-page has any touch-event handlers.
static bool HasTouchEventHandler(RenderViewHost* rvh);
virtual ~RenderViewHostTester() {}
// Gives tests access to RenderViewHostImpl::CreateRenderView.
virtual bool CreateTestRenderView(const base::string16& frame_name,
int opener_frame_route_id,
int proxy_routing_id,
bool created_with_opener) = 0;
// Makes the WasHidden/WasShown calls to the RenderWidget that
// tell it it has been hidden or restored from having been hidden.
virtual void SimulateWasHidden() = 0;
virtual void SimulateWasShown() = 0;
// Promote ComputeWebPreferences to public.
virtual WebPreferences TestComputeWebPreferences() = 0;
// You can instantiate only one class like this at a time. During its
// lifetime, RenderViewHost and RenderFrameHost objects created may be used via
// RenderViewHostTester and RenderFrameHostTester respectively.
class RenderViewHostTestEnabler {
friend class RenderViewHostTestHarness;
#if defined(OS_ANDROID)
std::unique_ptr<display::Screen> screen_;
#if defined(USE_AURA)
std::unique_ptr<ui::InputDeviceManager> input_device_client_;
std::unique_ptr<base::test::ScopedTaskEnvironment> task_environment_;
std::unique_ptr<MockRenderProcessHostFactory> rph_factory_;
std::unique_ptr<TestRenderViewHostFactory> rvh_factory_;
std::unique_ptr<TestRenderFrameHostFactory> rfh_factory_;
std::unique_ptr<TestRenderWidgetHostFactory> rwhi_factory_;
// RenderViewHostTestHarness ---------------------------------------------------
class RenderViewHostTestHarness : public testing::Test {
// Constructs a RenderViewHostTestHarness which uses |args| to initialize its
// TestBrowserThreadBundle.
template <typename... Args>
RenderViewHostTestHarness(Args... args)
: RenderViewHostTestHarness(
std::make_unique<TestBrowserThreadBundle>(args...)) {}
~RenderViewHostTestHarness() override;
NavigationController& controller();
// The contents under test.
WebContents* web_contents();
// RVH/RFH getters are shorthand for oft-used bits of web_contents().
// rvh() is equivalent to either of:
// web_contents()->GetMainFrame()->GetRenderViewHost()
// web_contents()->GetRenderViewHost()
RenderViewHost* rvh();
// pending_rvh() is equivalent to:
// WebContentsTester::For(web_contents())->GetPendingRenderViewHost()
RenderViewHost* pending_rvh();
// active_rvh() is equivalent to pending_rvh() ? pending_rvh() : rvh()
RenderViewHost* active_rvh();
// main_rfh() is equivalent to web_contents()->GetMainFrame()
RenderFrameHost* main_rfh();
// pending_main_rfh() is equivalent to:
// WebContentsTester::For(web_contents())->GetPendingMainFrame()
RenderFrameHost* pending_main_rfh();
BrowserContext* browser_context();
MockRenderProcessHost* process();
// Frees the current WebContents for tests that want to test destruction.
void DeleteContents();
// Sets the current WebContents for tests that want to alter it. Takes
// ownership of the WebContents passed.
void SetContents(std::unique_ptr<WebContents> contents);
// Creates a new test-enabled WebContents. Ownership passes to the
// caller.
std::unique_ptr<WebContents> CreateTestWebContents();
// Cover for |contents()->NavigateAndCommit(url)|. See
// WebContentsTester::NavigateAndCommit for details.
void NavigateAndCommit(const GURL& url);
// Sets the focused frame to the main frame of the WebContents for tests that
// rely on the focused frame not being null.
void FocusWebContentsOnMainFrame();
// testing::Test
void SetUp() override;
void TearDown() override;
// Derived classes should override this method to use a custom BrowserContext.
// It is invoked by SetUp after threads were started.
// RenderViewHostTestHarness will take ownership of the returned
// BrowserContext.
virtual BrowserContext* CreateBrowserContext();
// Derived classes can override this method to have the test harness use a
// different BrowserContext than the one owned by this class. This is most
// useful for off-the-record contexts, which are usually owned by the original
// context.
virtual BrowserContext* GetBrowserContext();
TestBrowserThreadBundle* thread_bundle() { return thread_bundle_.get(); }
#if defined(USE_AURA)
aura::Window* root_window() { return aura_test_helper_->root_window(); }
// Replaces the RPH being used.
void SetRenderProcessHostFactory(RenderProcessHostFactory* factory);
// The template constructor has to be in the header but it delegates to this
// constructor to initialize all other members out-of-line.
explicit RenderViewHostTestHarness(
std::unique_ptr<TestBrowserThreadBundle> thread_bundle);
std::unique_ptr<TestBrowserThreadBundle> thread_bundle_;
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
std::unique_ptr<ContentBrowserSanityChecker> sanity_checker_;
std::unique_ptr<BrowserContext> browser_context_;
// This must be placed before |contents_| such that it will be destructed
// after it. See
std::unique_ptr<RenderViewHostTestEnabler> rvh_test_enabler_;
std::unique_ptr<WebContents> contents_;
#if defined(OS_WIN)
std::unique_ptr<ui::ScopedOleInitializer> ole_initializer_;
#if defined(USE_AURA)
std::unique_ptr<aura::test::AuraTestHelper> aura_test_helper_;
RenderProcessHostFactory* factory_ = nullptr;
} // namespace content