2337 lines
71 KiB
C++
2337 lines
71 KiB
C++
// Copyright (c) 2014 The Chromium Embedded Framework 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 this first to avoid type conflicts with CEF headers.
|
|
#include "tests/unittests/chromium_includes.h"
|
|
|
|
#include "include/base/cef_bind.h"
|
|
#include "include/base/cef_scoped_ptr.h"
|
|
#include "include/wrapper/cef_closure_task.h"
|
|
#include "include/wrapper/cef_stream_resource_handler.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "tests/cefclient/client_app.h"
|
|
#include "tests/unittests/test_handler.h"
|
|
|
|
// Comment out this define to disable the unit test timeout.
|
|
#define TIMEOUT_ENABLED 1
|
|
|
|
namespace {
|
|
|
|
// The frame navigation test harness work as follows:
|
|
//
|
|
// In the browser process:
|
|
// 1. TEST() function creates a new FrameNavTestHandler instance with a unique
|
|
// FrameNavFactoryId.
|
|
// 2. FrameNavTestHandler calls FrameNavExpectationsFactoryBrowser::FromID to
|
|
// create a new factory instance.
|
|
// 3. FrameNavTestHandler calls FrameNavExpectationsFactoryBrowser::Create to
|
|
// create a new FrameNavExpectationsBrowser instance for the current
|
|
// navigation.
|
|
// 4. FrameNavTestHandler retrieves the URL to load via
|
|
// FrameNavExpectationsBrowser::GetMainURL and calls either CreateBrowser
|
|
// (for the first navigation) or LoadURL (for the following navigations).
|
|
// 5. If the renderer process does not already exist CEF creates it with
|
|
// command-line arguments that specify the FrameNavFactoryId via
|
|
// FrameNavBrowserTest::OnBeforeChildProcessLaunch.
|
|
//
|
|
// In the renderer process:
|
|
// 6. If the renderer process is newly created FrameNavRendererTest calls
|
|
// FrameNavExpectationsFactoryRenderer::FromID to create a new factory
|
|
// instance.
|
|
// 7. FrameNavRendererTest calls FrameNavExpectationsFactoryRenderer::Create to
|
|
// create a new FrameNavExpectationsRenderer instance for the current
|
|
// navigation.
|
|
//
|
|
// In both processes:
|
|
// 8. Callback notifications are sent to the FrameNavExpectations* instances.
|
|
//
|
|
// In the renderer process:
|
|
// 9. When the FrameNavExpectationsRenderer instance determines that the
|
|
// renderer side of the test is complete it calls SignalComplete which
|
|
// finalizes and deletes the FrameNavExpectationsRenderer instance and
|
|
// sends an IPC message to the browser process.
|
|
//
|
|
// In the browser process:
|
|
// 11.FrameNavExpectationsBrowser::OnRendererComplete is called in response to
|
|
// renderer-side test completion message.
|
|
// 12.When the FrameNavExpectationsBrowser instance determines that the browser
|
|
// side of the test is complete it calls SignalComplete which finalizes and
|
|
// deletes the FrameNavExpectationsBrowser instance.
|
|
// 13.If FrameNavExpectationsFactoryBrowser::HasMoreNavigations returns false
|
|
// then DestroyTest is called and the test ends. Otherwise, the navigation
|
|
// count is incremented and the process repeats starting with step #3.
|
|
//
|
|
//
|
|
// To add a new test case:
|
|
// 1. Add a new value to the FrameNavFactoryId enumeration.
|
|
// 2. Provide implementations of FrameNavExpectations*.
|
|
// 3. Add a case for the new factory ID to FrameNavExpectationsFactory*::FromID.
|
|
// 4. Implement a TEST() function that creates a FrameNavTestHandler instance
|
|
// and passes the new factory ID.
|
|
//
|
|
//
|
|
// Run with the `--single-process` command-line flag to see expectation failures
|
|
// from the renderer process.
|
|
//
|
|
|
|
// All known factory IDs.
|
|
enum FrameNavFactoryId {
|
|
FNF_ID_INVALID = 0,
|
|
FNF_ID_SINGLE_NAV_HARNESS,
|
|
FNF_ID_SINGLE_NAV,
|
|
FNF_ID_MULTI_NAV_HARNESS,
|
|
FNF_ID_MULTI_NAV,
|
|
FNF_ID_NESTED_IFRAMES_SAME_ORIGIN,
|
|
FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN,
|
|
};
|
|
|
|
// Command-line argument names.
|
|
const char kTestArg[] = "test";
|
|
const char kTestFactoryIdArg[] = "testfid";
|
|
|
|
// IPC message name.
|
|
const char kFrameNavMsg[] = "FrameTest.Navigation";
|
|
|
|
// Origins used in tests.
|
|
const char kFrameNavOrigin0[] = "http://tests-framenav0.com/";
|
|
const char kFrameNavOrigin1[] = "http://tests-framenav1.com/";
|
|
const char kFrameNavOrigin2[] = "http://tests-framenav2.com/";
|
|
|
|
// Maximum number of navigations. Should be kept synchronized with the number
|
|
// of kFrameNavOrigin* values. Don't modify this value without checking the
|
|
// below use cases.
|
|
const int kMaxMultiNavNavigations = 3;
|
|
|
|
// Global variables identifying the currently running test.
|
|
bool g_frame_nav_test = false;
|
|
FrameNavFactoryId g_frame_nav_factory_id = FNF_ID_INVALID;
|
|
|
|
|
|
// Abstract base class representing expectations that result from a navigation.
|
|
class FrameNavExpectations {
|
|
public:
|
|
typedef base::Callback<void(CefRefPtr<CefBrowser>)> CompletionCallback;
|
|
|
|
FrameNavExpectations(int nav, bool renderer)
|
|
: nav_(nav),
|
|
renderer_(renderer) {
|
|
}
|
|
virtual ~FrameNavExpectations() {}
|
|
|
|
// Browser and renderer notifications.
|
|
virtual bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) { return true; }
|
|
virtual bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) { return true; }
|
|
virtual bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) { return true; }
|
|
|
|
// Final expectations check before this object is deleted.
|
|
virtual bool Finalize() =0;
|
|
|
|
// Signal that all expectations are completed. Should be called as a result of
|
|
// notifications.
|
|
void SignalComplete(CefRefPtr<CefBrowser> browser) {
|
|
if (!completion_callback_.is_null()) {
|
|
// Execute the callback asynchronously to avoid any issues with what's
|
|
// currently on the stack.
|
|
CefPostTask((renderer_ ? TID_RENDERER: TID_UI),
|
|
base::Bind(completion_callback_, browser));
|
|
completion_callback_.Reset();
|
|
}
|
|
}
|
|
|
|
// Returns the current navigation count. In the browser process this value
|
|
// increments over the life span of the FrameNavTestHandler instance. In the
|
|
// renderer process this value increments over the life span of a single
|
|
// renderer instance (i.e. cross-origin navigations will cause this value to
|
|
// reset).
|
|
int nav() const { return nav_; }
|
|
|
|
// Returns true if this is a renderer-side expectation object.
|
|
bool renderer() const { return renderer_; }
|
|
|
|
void set_completion_callback(const CompletionCallback& completion_callback) {
|
|
completion_callback_ = completion_callback;
|
|
}
|
|
|
|
private:
|
|
int nav_;
|
|
bool renderer_;
|
|
CompletionCallback completion_callback_;
|
|
};
|
|
|
|
// Browser process expectations abstact base class.
|
|
class FrameNavExpectationsBrowser : public FrameNavExpectations {
|
|
public:
|
|
explicit FrameNavExpectationsBrowser(int nav)
|
|
: FrameNavExpectations(nav, false) {
|
|
}
|
|
|
|
// Loading information.
|
|
virtual std::string GetMainURL() =0;
|
|
virtual std::string GetContentForURL(const std::string& url) =0;
|
|
|
|
// Browser-only notifications.
|
|
virtual bool OnAfterCreated(CefRefPtr<CefBrowser> browser) { return true; }
|
|
virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) { return true; }
|
|
virtual bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) { return true; }
|
|
|
|
// Called when the renderer signals completion.
|
|
virtual bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) =0;
|
|
};
|
|
|
|
// Renderer process expectations abstract base class.
|
|
class FrameNavExpectationsRenderer : public FrameNavExpectations {
|
|
public:
|
|
explicit FrameNavExpectationsRenderer(int nav)
|
|
: FrameNavExpectations(nav, true) {
|
|
}
|
|
|
|
// Renderer-only notifications.
|
|
virtual bool OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) { return true; }
|
|
};
|
|
|
|
|
|
// Abstract base class for the factory that creates expectations objects.
|
|
class FrameNavExpectationsFactory {
|
|
public:
|
|
FrameNavExpectationsFactory() {}
|
|
virtual ~FrameNavExpectationsFactory() {}
|
|
|
|
// Returns the unique ID for this factory type.
|
|
virtual FrameNavFactoryId GetID() const =0;
|
|
};
|
|
|
|
// Browser process expectations factory abstact base class.
|
|
class FrameNavExpectationsFactoryBrowser : public FrameNavExpectationsFactory {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowser() {}
|
|
|
|
// Create a new factory instance of the specified type.
|
|
static scoped_ptr<FrameNavExpectationsFactoryBrowser>
|
|
FromID(FrameNavFactoryId id);
|
|
|
|
// Returns true if there will be more navigations in the browser process
|
|
// handler.
|
|
virtual bool HasMoreNavigations() const =0;
|
|
|
|
// Verify final expectations results.
|
|
virtual bool Finalize() =0;
|
|
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(
|
|
int nav,
|
|
const FrameNavExpectations::CompletionCallback& completion_callback) {
|
|
scoped_ptr<FrameNavExpectationsBrowser> expectations;
|
|
expectations = Create(nav);
|
|
expectations->set_completion_callback(completion_callback);
|
|
return expectations.Pass();
|
|
}
|
|
|
|
protected:
|
|
// Implement in the test-specific factory instance.
|
|
virtual scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) =0;
|
|
};
|
|
|
|
// Renderer process expectations factory abstact base class.
|
|
class FrameNavExpectationsFactoryRenderer : public FrameNavExpectationsFactory {
|
|
public:
|
|
FrameNavExpectationsFactoryRenderer() {}
|
|
|
|
// Create a new factory instance of the specified type.
|
|
static scoped_ptr<FrameNavExpectationsFactoryRenderer>
|
|
FromID(FrameNavFactoryId id);
|
|
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(
|
|
int nav,
|
|
const FrameNavExpectations::CompletionCallback& completion_callback) {
|
|
scoped_ptr<FrameNavExpectationsRenderer> expectations;
|
|
expectations = Create(nav);
|
|
expectations->set_completion_callback(completion_callback);
|
|
return expectations.Pass();
|
|
}
|
|
|
|
protected:
|
|
// Implement in the test-specific factory instance.
|
|
virtual scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) =0;
|
|
};
|
|
|
|
|
|
// Browser side app delegate.
|
|
class FrameNavBrowserTest : public ClientApp::BrowserDelegate {
|
|
public:
|
|
FrameNavBrowserTest() {}
|
|
|
|
void OnBeforeChildProcessLaunch(
|
|
CefRefPtr<ClientApp> app,
|
|
CefRefPtr<CefCommandLine> command_line) override {
|
|
if (!g_frame_nav_test)
|
|
return;
|
|
|
|
std::stringstream ss;
|
|
ss << g_frame_nav_factory_id;
|
|
|
|
// Indicate to the render process that the test should be run.
|
|
command_line->AppendSwitchWithValue(kTestArg, kFrameNavMsg);
|
|
command_line->AppendSwitchWithValue(kTestFactoryIdArg, ss.str());
|
|
}
|
|
|
|
protected:
|
|
IMPLEMENT_REFCOUNTING(FrameNavBrowserTest);
|
|
};
|
|
|
|
// Renderer side handler.
|
|
class FrameNavRendererTest : public ClientApp::RenderDelegate,
|
|
public CefLoadHandler {
|
|
public:
|
|
FrameNavRendererTest()
|
|
: run_test_(false),
|
|
nav_(0) {}
|
|
|
|
void OnRenderThreadCreated(
|
|
CefRefPtr<ClientApp> app,
|
|
CefRefPtr<CefListValue> extra_info) override {
|
|
// The g_* values will be set when running in single-process mode.
|
|
if (!g_frame_nav_test) {
|
|
// Check that the test should be run.
|
|
CefRefPtr<CefCommandLine> command_line =
|
|
CefCommandLine::GetGlobalCommandLine();
|
|
const std::string& test = command_line->GetSwitchValue(kTestArg);
|
|
if (test != kFrameNavMsg)
|
|
return;
|
|
}
|
|
|
|
FrameNavFactoryId factory_id = g_frame_nav_factory_id;
|
|
if (factory_id == FNF_ID_INVALID) {
|
|
// Retrieve the factory ID from the command-line.
|
|
CefRefPtr<CefCommandLine> command_line =
|
|
CefCommandLine::GetGlobalCommandLine();
|
|
if (command_line->HasSwitch(kTestFactoryIdArg)) {
|
|
factory_id = static_cast<FrameNavFactoryId>(
|
|
atoi(command_line->GetSwitchValue(
|
|
kTestFactoryIdArg).ToString().c_str()));
|
|
if (factory_id == FNF_ID_INVALID)
|
|
return;
|
|
}
|
|
}
|
|
|
|
run_test_ = true;
|
|
factory_ = FrameNavExpectationsFactoryRenderer::FromID(factory_id);
|
|
}
|
|
|
|
CefRefPtr<CefLoadHandler> GetLoadHandler(
|
|
CefRefPtr<ClientApp> app) override {
|
|
if (!run_test_)
|
|
return NULL;
|
|
|
|
return this;
|
|
}
|
|
|
|
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading,
|
|
bool canGoBack,
|
|
bool canGoForward) override {
|
|
CreateExpectationsIfNecessary();
|
|
EXPECT_TRUE(expectations_->OnLoadingStateChange(browser, isLoading)) <<
|
|
"isLoading = " << isLoading << ", nav = " << nav_;
|
|
}
|
|
|
|
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
CreateExpectationsIfNecessary();
|
|
EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_;
|
|
}
|
|
|
|
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
int httpStatusCode) override {
|
|
CreateExpectationsIfNecessary();
|
|
EXPECT_TRUE(expectations_->OnLoadEnd(browser, frame)) << "nav = " << nav_;
|
|
}
|
|
|
|
bool OnBeforeNavigation(CefRefPtr<ClientApp> app,
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefRequest> request,
|
|
cef_navigation_type_t navigation_type,
|
|
bool is_redirect) override {
|
|
if (!run_test_)
|
|
return false;
|
|
|
|
CreateExpectationsIfNecessary();
|
|
EXPECT_TRUE(expectations_->OnBeforeNavigation(browser, frame)) <<
|
|
"nav = " << nav_;
|
|
return false;
|
|
}
|
|
|
|
protected:
|
|
// Create a new expectations object if one does not already exist for the
|
|
// current navigation.
|
|
void CreateExpectationsIfNecessary() {
|
|
if (expectations_)
|
|
return;
|
|
expectations_ = factory_->Create(
|
|
nav_,
|
|
base::Bind(&FrameNavRendererTest::SendTestResults, this));
|
|
}
|
|
|
|
// Send the test results.
|
|
// Will be called via FrameNavExpectations::SignalComplete.
|
|
void SendTestResults(CefRefPtr<CefBrowser> browser) {
|
|
// End of the current expectations object.
|
|
EXPECT_TRUE(expectations_->Finalize()) << "nav = " << nav_;
|
|
expectations_.reset(NULL);
|
|
|
|
// Check if the test has failed.
|
|
bool result = !TestFailed();
|
|
|
|
// Return the result to the browser process.
|
|
CefRefPtr<CefProcessMessage> return_msg =
|
|
CefProcessMessage::Create(kFrameNavMsg);
|
|
CefRefPtr<CefListValue> args = return_msg->GetArgumentList();
|
|
EXPECT_TRUE(args.get());
|
|
EXPECT_TRUE(args->SetInt(0, nav_));
|
|
EXPECT_TRUE(args->SetBool(1, result));
|
|
EXPECT_TRUE(browser->SendProcessMessage(PID_BROWSER, return_msg));
|
|
|
|
nav_++;
|
|
}
|
|
|
|
bool run_test_;
|
|
int nav_;
|
|
scoped_ptr<FrameNavExpectationsFactoryRenderer> factory_;
|
|
scoped_ptr<FrameNavExpectationsRenderer> expectations_;
|
|
|
|
IMPLEMENT_REFCOUNTING(FrameNavRendererTest);
|
|
};
|
|
|
|
// Browser side handler.
|
|
class FrameNavTestHandler : public TestHandler {
|
|
public:
|
|
explicit FrameNavTestHandler(FrameNavFactoryId factory_id)
|
|
: nav_(0),
|
|
factory_(FrameNavExpectationsFactoryBrowser::FromID(factory_id))
|
|
#if defined(TIMEOUT_ENABLED)
|
|
, weak_ptr_factory_(this)
|
|
#endif
|
|
{
|
|
EXPECT_FALSE(g_frame_nav_test);
|
|
EXPECT_EQ(FNF_ID_INVALID, g_frame_nav_factory_id);
|
|
g_frame_nav_test = true;
|
|
g_frame_nav_factory_id = factory_id;
|
|
}
|
|
|
|
~FrameNavTestHandler() override {
|
|
EXPECT_TRUE(got_destroyed_);
|
|
g_frame_nav_test = false;
|
|
g_frame_nav_factory_id = FNF_ID_INVALID;
|
|
}
|
|
|
|
void RunTest() override {
|
|
// Create the first expectations object.
|
|
expectations_ = factory_->Create(
|
|
nav_,
|
|
base::Bind(&FrameNavTestHandler::RunNextNav, this));
|
|
|
|
// Create the browser with the initial URL.
|
|
CreateBrowser(expectations_->GetMainURL());
|
|
|
|
#if defined(TIMEOUT_ENABLED)
|
|
// Time out the test after a reasonable period of time.
|
|
CefPostDelayedTask(TID_UI,
|
|
base::Bind(&FrameNavTestHandler::DestroyTest,
|
|
weak_ptr_factory_.GetWeakPtr()),
|
|
4000);
|
|
#endif
|
|
}
|
|
|
|
// Transition to the next navigation.
|
|
// Will be called via FrameNavExpectations::SignalComplete.
|
|
void RunNextNav(CefRefPtr<CefBrowser> browser) {
|
|
// End of the current expectations object.
|
|
EXPECT_TRUE(expectations_->Finalize());
|
|
expectations_.reset(NULL);
|
|
|
|
if (!factory_->HasMoreNavigations()) {
|
|
// End of the test.
|
|
DestroyTest();
|
|
return;
|
|
}
|
|
|
|
nav_++;
|
|
|
|
// Create the next expectations object.
|
|
expectations_ = factory_->Create(
|
|
nav_,
|
|
base::Bind(&FrameNavTestHandler::RunNextNav, this));
|
|
|
|
// Load the main URL.
|
|
browser->GetMainFrame()->LoadURL(expectations_->GetMainURL());
|
|
}
|
|
|
|
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
TestHandler::OnAfterCreated(browser);
|
|
|
|
EXPECT_TRUE(expectations_->OnAfterCreated(browser)) << "nav = " << nav_;
|
|
}
|
|
|
|
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefRequest> request) override {
|
|
EXPECT_TRUE(expectations_->GetResourceHandler(browser, frame)) <<
|
|
"nav = " << nav_;
|
|
|
|
const std::string& url = request->GetURL();
|
|
const std::string& content = expectations_->GetContentForURL(url);
|
|
EXPECT_TRUE(!content.empty()) << "nav = " << nav_;
|
|
|
|
CefRefPtr<CefStreamReader> stream =
|
|
CefStreamReader::CreateForData(
|
|
static_cast<void*>(const_cast<char*>(content.c_str())),
|
|
content.length());
|
|
return new CefStreamResourceHandler("text/html", stream);
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefRequest> request,
|
|
bool is_redirect) override {
|
|
EXPECT_TRUE(expectations_->OnBeforeBrowse(browser, frame)) <<
|
|
"nav = " << nav_;
|
|
|
|
return false;
|
|
}
|
|
|
|
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading,
|
|
bool canGoBack,
|
|
bool canGoForward) override {
|
|
EXPECT_TRUE(expectations_->OnLoadingStateChange(browser, isLoading)) <<
|
|
"isLoading = " << isLoading << ", nav = " << nav_;;
|
|
}
|
|
|
|
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_;
|
|
}
|
|
|
|
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
int httpStatusCode) override {
|
|
EXPECT_TRUE(expectations_->OnLoadEnd(browser, frame)) << "nav = " << nav_;
|
|
}
|
|
|
|
bool OnProcessMessageReceived(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefProcessId source_process,
|
|
CefRefPtr<CefProcessMessage> message) override {
|
|
if (message->GetName().ToString() == kFrameNavMsg) {
|
|
// Test that the renderer side succeeded.
|
|
CefRefPtr<CefListValue> args = message->GetArgumentList();
|
|
EXPECT_TRUE(args.get());
|
|
|
|
EXPECT_TRUE(expectations_->OnRendererComplete(browser,
|
|
args->GetInt(0), args->GetBool(1))) << "nav = " << nav_;
|
|
return true;
|
|
}
|
|
|
|
// Message not handled.
|
|
return false;
|
|
}
|
|
|
|
void DestroyTest() override {
|
|
if (got_destroyed_)
|
|
return;
|
|
|
|
got_destroyed_.yes();
|
|
|
|
#if defined(TIMEOUT_ENABLED)
|
|
weak_ptr_factory_.InvalidateWeakPtrs();
|
|
#endif
|
|
|
|
// The expectations should have been tested already.
|
|
EXPECT_FALSE(expectations_.get());
|
|
|
|
// Test that factory conditions we met.
|
|
EXPECT_TRUE(factory_->Finalize()) << "nav = " << nav_;
|
|
|
|
TestHandler::DestroyTest();
|
|
}
|
|
|
|
int nav_;
|
|
TrackCallback got_destroyed_;
|
|
scoped_ptr<FrameNavExpectationsFactoryBrowser> factory_;
|
|
scoped_ptr<FrameNavExpectationsBrowser> expectations_;
|
|
|
|
#if defined(TIMEOUT_ENABLED)
|
|
// Must be the last member.
|
|
base::WeakPtrFactory<FrameNavTestHandler> weak_ptr_factory_;
|
|
#endif
|
|
};
|
|
|
|
|
|
// Wait for the the FrameNavTestHandler destructor to be called. This avoids
|
|
// problems with setting global variables when running multiple tests.
|
|
void WaitForTestHandlerDestruction() {
|
|
while (g_frame_nav_test)
|
|
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
|
|
}
|
|
|
|
// Helper for defining frame tests.
|
|
#define FRAME_TEST(name, factory_id) \
|
|
TEST(FrameTest, name) { \
|
|
CefRefPtr<FrameNavTestHandler> handler = \
|
|
new FrameNavTestHandler(factory_id); \
|
|
handler->ExecuteTest(); \
|
|
handler = NULL; \
|
|
WaitForTestHandlerDestruction(); \
|
|
}
|
|
|
|
|
|
// Browser process expectations for a single navigation.
|
|
class FrameNavExpectationsBrowserSingleNav :
|
|
public FrameNavExpectationsBrowser {
|
|
public:
|
|
explicit FrameNavExpectationsBrowserSingleNav(int nav)
|
|
: FrameNavExpectationsBrowser(nav) {
|
|
}
|
|
|
|
~FrameNavExpectationsBrowserSingleNav() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (isLoading) {
|
|
EXPECT_FALSE(got_loading_state_change_start_);
|
|
got_loading_state_change_start_.yes();
|
|
} else {
|
|
EXPECT_FALSE(got_loading_state_change_end_);
|
|
got_loading_state_change_end_.yes();
|
|
SignalCompleteIfDone(browser);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_load_start_);
|
|
got_load_start_.yes();
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_load_end_);
|
|
got_load_end_.yes();
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
EXPECT_FALSE(got_after_created_);
|
|
got_after_created_.yes();
|
|
return true;
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_before_browse_);
|
|
got_before_browse_.yes();
|
|
return true;
|
|
}
|
|
|
|
bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_get_resource_handler_);
|
|
got_get_resource_handler_.yes();
|
|
return true;
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
EXPECT_EQ(nav(), renderer_nav);
|
|
EXPECT_TRUE(renderer_result);
|
|
EXPECT_FALSE(got_renderer_done_);
|
|
got_renderer_done_.yes();
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_start_);
|
|
V_EXPECT_TRUE(got_load_end_);
|
|
V_EXPECT_TRUE(got_loading_state_change_start_);
|
|
V_EXPECT_TRUE(got_loading_state_change_end_);
|
|
V_EXPECT_TRUE(got_renderer_done_);
|
|
V_EXPECT_TRUE(got_after_created_);
|
|
V_EXPECT_TRUE(got_before_browse_);
|
|
V_EXPECT_TRUE(got_get_resource_handler_);
|
|
V_EXPECT_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser) {
|
|
if (got_renderer_done_ && got_load_end_ && got_loading_state_change_end_)
|
|
SignalComplete(browser);
|
|
}
|
|
|
|
TrackCallback got_load_start_;
|
|
TrackCallback got_load_end_;
|
|
TrackCallback got_loading_state_change_start_;
|
|
TrackCallback got_loading_state_change_end_;
|
|
TrackCallback got_renderer_done_;
|
|
TrackCallback got_after_created_;
|
|
TrackCallback got_before_browse_;
|
|
TrackCallback got_get_resource_handler_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
// Renderer process expectations for a single navigation.
|
|
class FrameNavExpectationsRendererSingleNav :
|
|
public FrameNavExpectationsRenderer {
|
|
public:
|
|
explicit FrameNavExpectationsRendererSingleNav(int nav)
|
|
: FrameNavExpectationsRenderer(nav) {
|
|
}
|
|
|
|
~FrameNavExpectationsRendererSingleNav() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (isLoading) {
|
|
EXPECT_FALSE(got_loading_state_change_start_);
|
|
got_loading_state_change_start_.yes();
|
|
} else {
|
|
EXPECT_FALSE(got_loading_state_change_end_);
|
|
got_loading_state_change_end_.yes();
|
|
SignalCompleteIfDone(browser);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_load_start_);
|
|
got_load_start_.yes();
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_load_end_);
|
|
got_load_end_.yes();
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_before_navigation_);
|
|
got_before_navigation_.yes();
|
|
return true;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_start_);
|
|
V_EXPECT_TRUE(got_load_end_);
|
|
V_EXPECT_TRUE(got_loading_state_change_start_);
|
|
V_EXPECT_TRUE(got_loading_state_change_end_);
|
|
V_EXPECT_TRUE(got_before_navigation_);
|
|
V_EXPECT_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser) {
|
|
if (got_load_end_ && got_loading_state_change_end_)
|
|
SignalComplete(browser);
|
|
}
|
|
|
|
TrackCallback got_load_start_;
|
|
TrackCallback got_load_end_;
|
|
TrackCallback got_loading_state_change_start_;
|
|
TrackCallback got_loading_state_change_end_;
|
|
TrackCallback got_before_navigation_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
// Test that the single nav harness works.
|
|
class FrameNavExpectationsBrowserTestSingleNavHarness :
|
|
public FrameNavExpectationsBrowserSingleNav {
|
|
public:
|
|
typedef FrameNavExpectationsBrowserSingleNav parent;
|
|
|
|
explicit FrameNavExpectationsBrowserTestSingleNavHarness(int nav)
|
|
: parent(nav) {
|
|
}
|
|
|
|
~FrameNavExpectationsBrowserTestSingleNavHarness() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
std::string GetMainURL() override {
|
|
EXPECT_FALSE(got_get_main_url_);
|
|
got_get_main_url_.yes();
|
|
return kFrameNavOrigin0;
|
|
}
|
|
|
|
std::string GetContentForURL(const std::string& url) override {
|
|
EXPECT_FALSE(got_get_content_for_url_);
|
|
got_get_content_for_url_.yes();
|
|
EXPECT_STREQ(kFrameNavOrigin0, url.c_str());
|
|
return "<html><body>Nav</body></html>";
|
|
}
|
|
|
|
bool Finalize() override {
|
|
EXPECT_FALSE(got_finalize_);
|
|
got_finalize_.yes();
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_get_main_url_);
|
|
V_EXPECT_TRUE(got_get_content_for_url_);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
TrackCallback got_get_main_url_;
|
|
TrackCallback got_get_content_for_url_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
class FrameNavExpectationsRendererTestSingleNavHarness :
|
|
public FrameNavExpectationsRendererSingleNav {
|
|
public:
|
|
typedef FrameNavExpectationsRendererSingleNav parent;
|
|
|
|
explicit FrameNavExpectationsRendererTestSingleNavHarness(int nav)
|
|
: parent(nav) {
|
|
}
|
|
|
|
~FrameNavExpectationsRendererTestSingleNavHarness() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
EXPECT_FALSE(got_finalize_);
|
|
got_finalize_.yes();
|
|
return parent::Finalize();
|
|
}
|
|
|
|
private:
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryBrowserTestSingleNavHarness :
|
|
public FrameNavExpectationsFactoryBrowser {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowserTestSingleNavHarness() {}
|
|
|
|
~FrameNavExpectationsFactoryBrowserTestSingleNavHarness() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_SINGLE_NAV_HARNESS;
|
|
}
|
|
|
|
bool HasMoreNavigations() const override {
|
|
EXPECT_FALSE(got_get_browser_navigation_count_);
|
|
got_get_browser_navigation_count_.yes();
|
|
return false;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
EXPECT_FALSE(got_finalize_);
|
|
got_finalize_.yes();
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_get_browser_navigation_count_);
|
|
V_EXPECT_TRUE(got_create_);
|
|
V_RETURN();
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
|
|
EXPECT_FALSE(got_create_);
|
|
got_create_.yes();
|
|
return make_scoped_ptr<FrameNavExpectationsBrowser>(
|
|
new FrameNavExpectationsBrowserTestSingleNavHarness(nav));
|
|
}
|
|
|
|
private:
|
|
mutable TrackCallback got_get_browser_navigation_count_;
|
|
TrackCallback got_create_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryRendererTestSingleNavHarness :
|
|
public FrameNavExpectationsFactoryRenderer {
|
|
public:
|
|
FrameNavExpectationsFactoryRendererTestSingleNavHarness() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_SINGLE_NAV_HARNESS;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsRenderer>(
|
|
new FrameNavExpectationsRendererTestSingleNavHarness(nav));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Test that the single nav harness works.
|
|
FRAME_TEST(SingleNavHarness, FNF_ID_SINGLE_NAV_HARNESS)
|
|
|
|
|
|
namespace {
|
|
|
|
bool VerifySingleBrowserFrame(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
bool frame_should_exist,
|
|
const std::string& expected_url) {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(frame.get());
|
|
V_EXPECT_TRUE(frame->IsValid());
|
|
if (frame_should_exist) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() >= 0);
|
|
} else {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == -4); // kInvalidFrameId
|
|
}
|
|
V_EXPECT_TRUE(frame->IsValid());
|
|
V_EXPECT_TRUE(frame->IsMain());
|
|
V_EXPECT_TRUE(frame->IsFocused());
|
|
V_EXPECT_FALSE(frame->GetParent().get());
|
|
V_EXPECT_TRUE(frame->GetName().empty());
|
|
V_EXPECT_TRUE(browser->GetIdentifier() ==
|
|
frame->GetBrowser()->GetIdentifier());
|
|
|
|
const std::string& frame_url = frame->GetURL();
|
|
V_EXPECT_TRUE(frame_url == expected_url) << "frame_url = " << frame_url <<
|
|
", expected_url = " << expected_url;
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
bool VerifySingleBrowserFrames(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
bool frame_should_exist,
|
|
const std::string& expected_url) {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(browser.get());
|
|
|
|
// |frame| may be NULL for callbacks that don't specify one.
|
|
if (frame.get()) {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, frame,
|
|
frame_should_exist, expected_url));
|
|
}
|
|
|
|
CefRefPtr<CefFrame> main_frame = browser->GetMainFrame();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, main_frame,
|
|
frame_should_exist, expected_url));
|
|
|
|
CefRefPtr<CefFrame> focused_frame = browser->GetFocusedFrame();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, focused_frame,
|
|
frame_should_exist, expected_url));
|
|
|
|
size_t frame_count = browser->GetFrameCount();
|
|
if (frame_should_exist) {
|
|
V_EXPECT_TRUE(frame_count == 1U);
|
|
|
|
std::vector<int64> identifiers;
|
|
browser->GetFrameIdentifiers(identifiers);
|
|
V_EXPECT_TRUE(identifiers.size() == 1U);
|
|
if (identifiers.size() == 1U) {
|
|
V_EXPECT_TRUE(identifiers[0] == main_frame->GetIdentifier());
|
|
V_EXPECT_TRUE(identifiers[0] == focused_frame->GetIdentifier());
|
|
}
|
|
|
|
std::vector<CefString> names;
|
|
browser->GetFrameNames(names);
|
|
V_EXPECT_TRUE(names.size() == 1U);
|
|
if (names.size() == 1U) {
|
|
V_EXPECT_TRUE(names[0].ToString() == main_frame->GetName().ToString());
|
|
V_EXPECT_TRUE(names[0].ToString() == focused_frame->GetName().ToString());
|
|
}
|
|
} else {
|
|
V_EXPECT_TRUE(frame_count == 0U);
|
|
}
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
// Test that single navigation works.
|
|
class FrameNavExpectationsBrowserTestSingleNav :
|
|
public FrameNavExpectationsBrowserSingleNav {
|
|
public:
|
|
typedef FrameNavExpectationsBrowserSingleNav parent;
|
|
|
|
explicit FrameNavExpectationsBrowserTestSingleNav(int nav)
|
|
: parent(nav) {
|
|
}
|
|
|
|
std::string GetMainURL() override {
|
|
return kFrameNavOrigin0;
|
|
}
|
|
|
|
std::string GetContentForURL(const std::string& url) override {
|
|
return "<html><body>Nav</body></html>";
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
V_DECLARE();
|
|
if (isLoading) {
|
|
// No frame exists before the first load.
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, false,
|
|
std::string()));
|
|
} else {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
kFrameNavOrigin0));
|
|
}
|
|
V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
kFrameNavOrigin0));
|
|
V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
kFrameNavOrigin0));
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, false,
|
|
std::string()));
|
|
V_EXPECT_TRUE(parent::OnAfterCreated(browser));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
std::string()));
|
|
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
std::string()));
|
|
V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
return parent::OnRendererComplete(browser, renderer_nav, renderer_result);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
return parent::Finalize();
|
|
}
|
|
};
|
|
|
|
class FrameNavExpectationsRendererTestSingleNav :
|
|
public FrameNavExpectationsRendererSingleNav {
|
|
public:
|
|
typedef FrameNavExpectationsRendererSingleNav parent;
|
|
|
|
explicit FrameNavExpectationsRendererTestSingleNav(int nav)
|
|
: parent(nav) {
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
V_DECLARE();
|
|
// A frame should always exist in the renderer process.
|
|
if (isLoading) {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
std::string()));
|
|
} else {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
kFrameNavOrigin0));
|
|
}
|
|
V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
kFrameNavOrigin0));
|
|
V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
kFrameNavOrigin0));
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool Finalize() override {
|
|
return parent::Finalize();
|
|
}
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryBrowserTestSingleNav :
|
|
public FrameNavExpectationsFactoryBrowser {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowserTestSingleNav() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_SINGLE_NAV;
|
|
}
|
|
|
|
bool HasMoreNavigations() const override {
|
|
return false;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
return true;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsBrowser>(
|
|
new FrameNavExpectationsBrowserTestSingleNav(nav));
|
|
}
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryRendererTestSingleNav :
|
|
public FrameNavExpectationsFactoryRenderer {
|
|
public:
|
|
FrameNavExpectationsFactoryRendererTestSingleNav() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_SINGLE_NAV;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsRenderer>(
|
|
new FrameNavExpectationsRendererTestSingleNav(nav));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Test that single navigation works.
|
|
FRAME_TEST(SingleNav, FNF_ID_SINGLE_NAV)
|
|
|
|
|
|
namespace {
|
|
|
|
// Browser process expectations for a multiple navigations.
|
|
class FrameNavExpectationsBrowserMultiNav :
|
|
public FrameNavExpectationsBrowser {
|
|
public:
|
|
explicit FrameNavExpectationsBrowserMultiNav(int nav)
|
|
: FrameNavExpectationsBrowser(nav) {
|
|
}
|
|
|
|
~FrameNavExpectationsBrowserMultiNav() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
// Returns true if all navigation is done.
|
|
virtual bool IsNavigationDone() const =0;
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (!isLoading)
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
EXPECT_TRUE(renderer_result);
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser) {
|
|
if (IsNavigationDone())
|
|
SignalComplete(browser);
|
|
}
|
|
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
// Renderer process expectations for a multiple navigations.
|
|
class FrameNavExpectationsRendererMultiNav :
|
|
public FrameNavExpectationsRenderer {
|
|
public:
|
|
explicit FrameNavExpectationsRendererMultiNav(int nav)
|
|
: FrameNavExpectationsRenderer(nav) {
|
|
}
|
|
|
|
~FrameNavExpectationsRendererMultiNav() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
// Returns true if all navigation is done.
|
|
virtual bool IsNavigationDone() const =0;
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (!isLoading)
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
SignalCompleteIfDone(browser);
|
|
return true;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser) {
|
|
if (IsNavigationDone())
|
|
SignalComplete(browser);
|
|
}
|
|
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
|
|
// Create a URL containing the nav number.
|
|
std::string GetMultiNavURL(const std::string& origin, int nav) {
|
|
std::stringstream ss;
|
|
ss << origin << "nav" << nav << ".html";
|
|
return ss.str();
|
|
}
|
|
|
|
// Extract the nav number from the URL.
|
|
int GetNavFromMultiNavURL(const std::string& url) {
|
|
const size_t start = url.find("/nav");
|
|
const size_t end = url.find(".html", start);
|
|
EXPECT_TRUE(start < end && start > 0U);
|
|
const std::string& nav = url.substr(start + 4, end - start - 4);
|
|
return atoi(nav.c_str());
|
|
}
|
|
|
|
// Extract the origin from the URL.
|
|
std::string GetOriginFromMultiNavURL(const std::string& url) {
|
|
const size_t pos = url.rfind("/");
|
|
EXPECT_TRUE(pos > 0U);
|
|
return url.substr(0, pos + 1);
|
|
}
|
|
|
|
// Test that the multi nav harness works.
|
|
class FrameNavExpectationsBrowserTestMultiNavHarness :
|
|
public FrameNavExpectationsBrowserMultiNav {
|
|
public:
|
|
typedef FrameNavExpectationsBrowserMultiNav parent;
|
|
|
|
explicit FrameNavExpectationsBrowserTestMultiNavHarness(int nav)
|
|
: parent(nav),
|
|
navigation_done_count_(0) {
|
|
}
|
|
|
|
~FrameNavExpectationsBrowserTestMultiNavHarness() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
std::string GetMainURL() override {
|
|
EXPECT_FALSE(got_get_main_url_);
|
|
got_get_main_url_.yes();
|
|
return GetMultiNavURL(kFrameNavOrigin0, nav());
|
|
}
|
|
|
|
std::string GetContentForURL(const std::string& url) override {
|
|
EXPECT_FALSE(got_get_content_for_url_);
|
|
got_get_content_for_url_.yes();
|
|
EXPECT_STREQ(GetMultiNavURL(kFrameNavOrigin0, nav()).c_str(), url.c_str());
|
|
return "<html><body>Nav</body></html>";
|
|
}
|
|
|
|
bool IsNavigationDone() const override {
|
|
navigation_done_count_++;
|
|
return got_load_state_change_done_ && got_load_end_ &&
|
|
got_renderer_complete_;
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (!isLoading) {
|
|
EXPECT_FALSE(got_load_state_change_done_);
|
|
got_load_state_change_done_.yes();
|
|
}
|
|
return parent::OnLoadingStateChange(browser, isLoading);
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_load_end_);
|
|
got_load_end_.yes();
|
|
return parent::OnLoadEnd(browser, frame);
|
|
}
|
|
|
|
bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
EXPECT_FALSE(got_on_after_created_);
|
|
got_on_after_created_.yes();
|
|
return parent::OnAfterCreated(browser);
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
EXPECT_FALSE(got_renderer_complete_);
|
|
got_renderer_complete_.yes();
|
|
EXPECT_EQ(nav(), renderer_nav);
|
|
return parent::OnRendererComplete(browser, renderer_nav, renderer_result);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
EXPECT_FALSE(got_finalize_);
|
|
got_finalize_.yes();
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_get_main_url_);
|
|
V_EXPECT_TRUE(got_get_content_for_url_);
|
|
V_EXPECT_TRUE(got_load_state_change_done_);
|
|
V_EXPECT_TRUE(got_load_end_);
|
|
if (nav() == 0) {
|
|
V_EXPECT_TRUE(got_on_after_created_);
|
|
} else {
|
|
V_EXPECT_FALSE(got_on_after_created_);
|
|
}
|
|
V_EXPECT_TRUE(got_renderer_complete_);
|
|
V_EXPECT_TRUE(navigation_done_count_ == 3);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
TrackCallback got_get_main_url_;
|
|
TrackCallback got_get_content_for_url_;
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_end_;
|
|
TrackCallback got_on_after_created_;
|
|
TrackCallback got_renderer_complete_;
|
|
mutable int navigation_done_count_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
class FrameNavExpectationsRendererTestMultiNavHarness :
|
|
public FrameNavExpectationsRendererMultiNav {
|
|
public:
|
|
typedef FrameNavExpectationsRendererMultiNav parent;
|
|
|
|
explicit FrameNavExpectationsRendererTestMultiNavHarness(int nav)
|
|
: parent(nav),
|
|
navigation_done_count_(0) {
|
|
}
|
|
|
|
~FrameNavExpectationsRendererTestMultiNavHarness() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
bool IsNavigationDone() const override {
|
|
navigation_done_count_++;
|
|
return got_load_state_change_done_ && got_load_end_;
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (!isLoading) {
|
|
EXPECT_FALSE(got_load_state_change_done_);
|
|
got_load_state_change_done_.yes();
|
|
}
|
|
return parent::OnLoadingStateChange(browser, isLoading);
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
EXPECT_FALSE(got_load_end_);
|
|
got_load_end_.yes();
|
|
return parent::OnLoadEnd(browser, frame);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
EXPECT_FALSE(got_finalize_);
|
|
got_finalize_.yes();
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_state_change_done_);
|
|
V_EXPECT_TRUE(got_load_end_);
|
|
V_EXPECT_TRUE(navigation_done_count_ == 2);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_end_;
|
|
mutable int navigation_done_count_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryBrowserTestMultiNavHarness :
|
|
public FrameNavExpectationsFactoryBrowser {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowserTestMultiNavHarness()
|
|
: get_browser_navigation_count_(0),
|
|
create_count_(0) {}
|
|
|
|
~FrameNavExpectationsFactoryBrowserTestMultiNavHarness() override {
|
|
EXPECT_TRUE(got_finalize_);
|
|
}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_MULTI_NAV_HARNESS;
|
|
}
|
|
|
|
bool HasMoreNavigations() const override {
|
|
get_browser_navigation_count_++;
|
|
return (get_browser_navigation_count_ < kMaxMultiNavNavigations);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
EXPECT_FALSE(got_finalize_);
|
|
got_finalize_.yes();
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(get_browser_navigation_count_ == kMaxMultiNavNavigations);
|
|
V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
|
|
V_RETURN();
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
|
|
create_count_++;
|
|
return make_scoped_ptr<FrameNavExpectationsBrowser>(
|
|
new FrameNavExpectationsBrowserTestMultiNavHarness(nav));
|
|
}
|
|
|
|
private:
|
|
mutable int get_browser_navigation_count_;
|
|
int create_count_;
|
|
TrackCallback got_finalize_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryRendererTestMultiNavHarness :
|
|
public FrameNavExpectationsFactoryRenderer {
|
|
public:
|
|
FrameNavExpectationsFactoryRendererTestMultiNavHarness() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_MULTI_NAV_HARNESS;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsRenderer>(
|
|
new FrameNavExpectationsRendererTestMultiNavHarness(nav));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Test that the multiple nav harness works.
|
|
FRAME_TEST(MultiNavHarness, FNF_ID_MULTI_NAV_HARNESS)
|
|
|
|
|
|
namespace {
|
|
|
|
// Test that multiple navigation works.
|
|
class FrameNavExpectationsBrowserTestMultiNav :
|
|
public FrameNavExpectationsBrowserMultiNav {
|
|
public:
|
|
typedef FrameNavExpectationsBrowserMultiNav parent;
|
|
|
|
explicit FrameNavExpectationsBrowserTestMultiNav(int nav)
|
|
: parent(nav) {
|
|
}
|
|
|
|
std::string GetMainURL() override {
|
|
return GetMultiNavURL(kFrameNavOrigin0, nav());
|
|
}
|
|
|
|
std::string GetContentForURL(const std::string& url) override {
|
|
return "<html><body>Nav</body></html>";
|
|
}
|
|
|
|
bool IsNavigationDone() const override {
|
|
return got_load_state_change_done_ && got_load_end_ &&
|
|
got_renderer_complete_;
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (!isLoading)
|
|
got_load_state_change_done_.yes();
|
|
V_DECLARE();
|
|
// A frame should exist in all cases except for the very first load.
|
|
if (isLoading && nav() == 0) {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, false,
|
|
std::string()));
|
|
} else if (isLoading) {
|
|
// Expect the URL from the previous load.
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
GetPreviousMainURL()));
|
|
} else {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
GetMainURL()));
|
|
}
|
|
V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
GetMainURL()));
|
|
V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
got_load_end_.yes();
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
GetMainURL()));
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, false,
|
|
std::string()));
|
|
V_EXPECT_TRUE(parent::OnAfterCreated(browser));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
std::string expected_url;
|
|
if (nav() > 0)
|
|
expected_url = GetPreviousMainURL();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
expected_url));
|
|
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
std::string expected_url;
|
|
if (nav() > 0)
|
|
expected_url = GetPreviousMainURL();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
expected_url));
|
|
V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
got_renderer_complete_.yes();
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(nav() == renderer_nav);
|
|
V_EXPECT_TRUE(parent::OnRendererComplete(browser, renderer_nav,
|
|
renderer_result));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_state_change_done_);
|
|
V_EXPECT_TRUE(got_load_end_);
|
|
V_EXPECT_TRUE(got_renderer_complete_);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
// Helper for VerifySingleBrowserFrames.
|
|
std::string GetPreviousMainURL() {
|
|
EXPECT_GT(nav(), 0);
|
|
return GetMultiNavURL(kFrameNavOrigin0, nav() - 1);
|
|
}
|
|
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_end_;
|
|
TrackCallback got_renderer_complete_;
|
|
};
|
|
|
|
class FrameNavExpectationsRendererTestMultiNav :
|
|
public FrameNavExpectationsRendererMultiNav {
|
|
public:
|
|
typedef FrameNavExpectationsRendererMultiNav parent;
|
|
|
|
explicit FrameNavExpectationsRendererTestMultiNav(int nav)
|
|
: parent(nav) {
|
|
}
|
|
|
|
bool IsNavigationDone() const override {
|
|
return got_load_state_change_done_ && got_load_end_;
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
if (!isLoading)
|
|
got_load_state_change_done_.yes();
|
|
V_DECLARE();
|
|
// A frame should always exist in the renderer process.
|
|
if (isLoading) {
|
|
std::string expected_url;
|
|
if (nav() > 0)
|
|
expected_url = GetPreviousMainURL();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
expected_url));
|
|
} else {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, true,
|
|
GetMainURL()));
|
|
}
|
|
V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
GetMainURL()));
|
|
V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
got_load_end_.yes();
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, true,
|
|
GetMainURL()));
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_state_change_done_);
|
|
V_EXPECT_TRUE(got_load_end_);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
// Helpers for calling VerifySingleBrowserFrames.
|
|
std::string GetMainURL() const {
|
|
return GetMultiNavURL(kFrameNavOrigin0, nav());
|
|
}
|
|
std::string GetPreviousMainURL() {
|
|
EXPECT_GT(nav(), 0);
|
|
return GetMultiNavURL(kFrameNavOrigin0, nav() - 1);
|
|
}
|
|
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_end_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryBrowserTestMultiNav :
|
|
public FrameNavExpectationsFactoryBrowser {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowserTestMultiNav()
|
|
: nav_count_(0) {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_MULTI_NAV;
|
|
}
|
|
|
|
bool HasMoreNavigations() const override {
|
|
return (nav_count_ < kMaxMultiNavNavigations);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(nav_count_ == kMaxMultiNavNavigations);
|
|
V_RETURN();
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
|
|
nav_count_++;
|
|
return make_scoped_ptr<FrameNavExpectationsBrowser>(
|
|
new FrameNavExpectationsBrowserTestMultiNav(nav));
|
|
}
|
|
|
|
private:
|
|
int nav_count_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryRendererTestMultiNav :
|
|
public FrameNavExpectationsFactoryRenderer {
|
|
public:
|
|
FrameNavExpectationsFactoryRendererTestMultiNav() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_MULTI_NAV;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsRenderer>(
|
|
new FrameNavExpectationsRendererTestMultiNav(nav));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Test that multiple navigation works.
|
|
FRAME_TEST(MultiNav, FNF_ID_MULTI_NAV)
|
|
|
|
|
|
namespace {
|
|
|
|
const char kFrame0Name[] = "";
|
|
const char kFrame1Name[] = "nav2";
|
|
const char kFrame2Name[] = "<!--framePath //nav2/<!--frame0-->-->";
|
|
|
|
bool VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const std::string& origin,
|
|
int frame_number) {
|
|
V_DECLARE();
|
|
|
|
// frame0 contains frame1 contains frame2.
|
|
CefRefPtr<CefFrame> frame0, frame1, frame2;
|
|
CefRefPtr<CefFrame> frame0b, frame1b, frame2b;
|
|
int64 frame0id, frame1id, frame2id;
|
|
std::string frame0url, frame1url, frame2url;
|
|
|
|
// Find frames by name.
|
|
frame0 = browser->GetFrame(kFrame0Name);
|
|
V_EXPECT_TRUE(frame0.get());
|
|
frame1 = browser->GetFrame(kFrame1Name);
|
|
V_EXPECT_TRUE(frame1.get());
|
|
frame2 = browser->GetFrame(kFrame2Name);
|
|
V_EXPECT_TRUE(frame2.get());
|
|
|
|
// Verify that the name matches.
|
|
V_EXPECT_TRUE(frame0->GetName().ToString() == kFrame0Name);
|
|
V_EXPECT_TRUE(frame1->GetName().ToString() == kFrame1Name);
|
|
V_EXPECT_TRUE(frame2->GetName().ToString() == kFrame2Name);
|
|
|
|
// Verify that the URL matches.
|
|
frame0url = GetMultiNavURL(origin, 0);
|
|
V_EXPECT_TRUE(frame0->GetURL() == frame0url);
|
|
frame1url = GetMultiNavURL(origin, 1);
|
|
V_EXPECT_TRUE(frame1->GetURL() == frame1url);
|
|
frame2url = GetMultiNavURL(origin, 2);
|
|
V_EXPECT_TRUE(frame2->GetURL() == frame2url);
|
|
|
|
// Verify that the frame id is valid.
|
|
frame0id = frame0->GetIdentifier();
|
|
V_EXPECT_TRUE(frame0id > 0);
|
|
frame1id = frame1->GetIdentifier();
|
|
V_EXPECT_TRUE(frame1id > 0);
|
|
frame2id = frame2->GetIdentifier();
|
|
V_EXPECT_TRUE(frame2id > 0);
|
|
|
|
// Verify that the current frame has the correct id.
|
|
if (frame_number == 0) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame0id);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame1id);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame2id);
|
|
}
|
|
|
|
// Find frames by id.
|
|
frame0b = browser->GetFrame(frame0->GetIdentifier());
|
|
V_EXPECT_TRUE(frame0b.get());
|
|
frame1b = browser->GetFrame(frame1->GetIdentifier());
|
|
V_EXPECT_TRUE(frame1b.get());
|
|
frame2b = browser->GetFrame(frame2->GetIdentifier());
|
|
V_EXPECT_TRUE(frame2b.get());
|
|
|
|
// Verify that the id matches.
|
|
V_EXPECT_TRUE(frame0b->GetIdentifier() == frame0id);
|
|
V_EXPECT_TRUE(frame1b->GetIdentifier() == frame1id);
|
|
V_EXPECT_TRUE(frame2b->GetIdentifier() == frame2id);
|
|
|
|
V_EXPECT_TRUE(browser->GetFrameCount() == 3U);
|
|
|
|
// Verify the GetFrameNames result.
|
|
std::vector<CefString> names;
|
|
browser->GetFrameNames(names);
|
|
V_EXPECT_TRUE(names.size() == 3U);
|
|
V_EXPECT_TRUE(names[0].ToString() == kFrame0Name);
|
|
V_EXPECT_TRUE(names[1].ToString() == kFrame1Name);
|
|
V_EXPECT_TRUE(names[2].ToString() == kFrame2Name);
|
|
|
|
// Verify the GetFrameIdentifiers result.
|
|
std::vector<int64> idents;
|
|
browser->GetFrameIdentifiers(idents);
|
|
V_EXPECT_TRUE(idents.size() == 3U);
|
|
V_EXPECT_TRUE(idents[0] == frame0->GetIdentifier());
|
|
V_EXPECT_TRUE(idents[1] == frame1->GetIdentifier());
|
|
V_EXPECT_TRUE(idents[2] == frame2->GetIdentifier());
|
|
|
|
// Verify parent hierarchy.
|
|
V_EXPECT_FALSE(frame0->GetParent().get());
|
|
V_EXPECT_TRUE(frame1->GetParent()->GetIdentifier() == frame0id);
|
|
V_EXPECT_TRUE(frame2->GetParent()->GetIdentifier() == frame1id);
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
// Test that nested iframes work.
|
|
class FrameNavExpectationsBrowserTestNestedIframes :
|
|
public FrameNavExpectationsBrowserMultiNav {
|
|
public:
|
|
typedef FrameNavExpectationsBrowserMultiNav parent;
|
|
|
|
FrameNavExpectationsBrowserTestNestedIframes(int nav, bool same_origin)
|
|
: parent(nav),
|
|
same_origin_(same_origin) {
|
|
// In the browser process we can rely on the |nav| value to determine the
|
|
// origin.
|
|
if (same_origin) {
|
|
origin_ = kFrameNavOrigin0;
|
|
} else switch (nav) {
|
|
case 0:
|
|
origin_ = kFrameNavOrigin0;
|
|
break;
|
|
case 1:
|
|
origin_ = kFrameNavOrigin1;
|
|
break;
|
|
case 2:
|
|
origin_ = kFrameNavOrigin2;
|
|
break;
|
|
default:
|
|
EXPECT_TRUE(false); // Not reached.
|
|
break;
|
|
}
|
|
}
|
|
|
|
std::string GetMainURL() override {
|
|
// Load the first (main) frame.
|
|
return GetMultiNavURL(origin_, 0);
|
|
}
|
|
|
|
std::string GetContentForURL(const std::string& url) override {
|
|
const int frame_number = GetNavFromMultiNavURL(url);
|
|
switch (frame_number) {
|
|
case 0:
|
|
// Frame 0. Contains a named iframe.
|
|
return "<html><body>Nav1<iframe src=\"" +
|
|
GetMultiNavURL(origin_, 1) +
|
|
"\" name=\"nav2\"></body></html>";
|
|
case 1:
|
|
// Frame 1. Contains an unnamed iframe.
|
|
return "<html><body>Nav2<iframe src=\"" +
|
|
GetMultiNavURL(origin_, 2) +
|
|
"\"></body></html>";
|
|
case 2:
|
|
// Frame 2.
|
|
return "<html><body>Nav3</body></html>";
|
|
default:
|
|
EXPECT_TRUE(false); // Not reached.
|
|
return "";
|
|
}
|
|
}
|
|
|
|
bool IsNavigationDone() const override {
|
|
return got_load_state_change_done_ && got_renderer_complete_ &&
|
|
got_load_end_[0] && got_load_end_[1] && got_load_end_[2];
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_load_state_change_done_);
|
|
|
|
if (!isLoading) {
|
|
got_load_state_change_done_.yes();
|
|
}
|
|
|
|
V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_load_start_[frame_number]);
|
|
V_EXPECT_FALSE(got_load_end_[frame_number]);
|
|
|
|
// Notification should be received for parent frame before child frame.
|
|
if (frame_number == 0) {
|
|
V_EXPECT_FALSE(got_load_start_[1]);
|
|
V_EXPECT_FALSE(got_load_start_[2]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_FALSE(got_load_start_[2]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
}
|
|
|
|
got_load_start_[frame_number].yes();
|
|
|
|
V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_start_[frame_number]);
|
|
V_EXPECT_FALSE(got_load_end_[frame_number]);
|
|
|
|
// Notification should be received for child frame before parent frame.
|
|
if (frame_number == 0) {
|
|
V_EXPECT_TRUE(got_load_end_[1]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_FALSE(got_load_end_[1]);
|
|
}
|
|
|
|
V_EXPECT_TRUE(VerifyBrowserIframe(browser, frame, origin_, frame_number)) <<
|
|
"frame_number = " << frame_number;
|
|
|
|
got_load_end_[frame_number].yes();
|
|
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_renderer_complete_);
|
|
if (same_origin_) {
|
|
V_EXPECT_TRUE(renderer_nav == nav());
|
|
} else {
|
|
// Because each navigation is in a new renderer process.
|
|
V_EXPECT_TRUE(renderer_nav == 0);
|
|
}
|
|
|
|
got_renderer_complete_.yes();
|
|
|
|
V_EXPECT_TRUE(parent::OnRendererComplete(browser, renderer_nav,
|
|
renderer_result));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_state_change_done_);
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
V_EXPECT_TRUE(got_load_start_[2]);
|
|
V_EXPECT_TRUE(got_load_end_[0]);
|
|
V_EXPECT_TRUE(got_load_end_[1]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
V_EXPECT_TRUE(got_renderer_complete_);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
bool same_origin_;
|
|
std::string origin_;
|
|
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_start_[3];
|
|
TrackCallback got_load_end_[3];
|
|
TrackCallback got_renderer_complete_;
|
|
};
|
|
|
|
class FrameNavExpectationsRendererTestNestedIframes :
|
|
public FrameNavExpectationsRendererMultiNav {
|
|
public:
|
|
typedef FrameNavExpectationsRendererMultiNav parent;
|
|
|
|
FrameNavExpectationsRendererTestNestedIframes(int nav, bool same_origin)
|
|
: parent(nav) {
|
|
if (same_origin)
|
|
origin_ = kFrameNavOrigin0;
|
|
}
|
|
|
|
bool IsNavigationDone() const override {
|
|
return got_load_state_change_done_ &&
|
|
got_load_end_[0] && got_load_end_[1] && got_load_end_[2];
|
|
}
|
|
|
|
bool OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|
bool isLoading) override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_load_state_change_done_);
|
|
|
|
if (!isLoading) {
|
|
got_load_state_change_done_.yes();
|
|
}
|
|
|
|
V_EXPECT_TRUE(parent::OnLoadingStateChange(browser, isLoading));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
if (origin_.empty()) {
|
|
// When navigating different origins we can't rely on the nav() value
|
|
// because each navigation creates a new renderer process. Get the origin
|
|
// by parsing the URL instead.
|
|
origin_ = GetOriginFromMultiNavURL(browser->GetMainFrame()->GetURL());
|
|
}
|
|
|
|
const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_load_start_[frame_number]);
|
|
V_EXPECT_FALSE(got_load_end_[frame_number]);
|
|
|
|
// Notification should be received for parent frame before child frame.
|
|
if (frame_number == 0) {
|
|
V_EXPECT_FALSE(got_load_start_[1]);
|
|
V_EXPECT_FALSE(got_load_start_[2]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_FALSE(got_load_start_[2]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
}
|
|
|
|
got_load_start_[frame_number].yes();
|
|
|
|
V_EXPECT_TRUE(parent::OnLoadStart(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
const int frame_number = GetNavFromMultiNavURL(frame->GetURL());
|
|
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_start_[frame_number]);
|
|
V_EXPECT_FALSE(got_load_end_[frame_number]);
|
|
|
|
// Notification should be received for child frame before parent frame.
|
|
if (frame_number == 0) {
|
|
V_EXPECT_TRUE(got_load_end_[1]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_FALSE(got_load_end_[1]);
|
|
}
|
|
|
|
V_EXPECT_TRUE(VerifyBrowserIframe(browser, frame, origin_, frame_number)) <<
|
|
"frame_number = " << frame_number;
|
|
|
|
got_load_end_[frame_number].yes();
|
|
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(got_load_state_change_done_);
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
V_EXPECT_TRUE(got_load_start_[2]);
|
|
V_EXPECT_TRUE(got_load_end_[0]);
|
|
V_EXPECT_TRUE(got_load_end_[1]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
std::string origin_;
|
|
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_start_[3];
|
|
TrackCallback got_load_end_[3];
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin :
|
|
public FrameNavExpectationsFactoryBrowser {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin()
|
|
: create_count_(0) {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_NESTED_IFRAMES_SAME_ORIGIN;
|
|
}
|
|
|
|
bool HasMoreNavigations() const override {
|
|
return (create_count_ < kMaxMultiNavNavigations);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
|
|
V_RETURN();
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
|
|
create_count_++;
|
|
return make_scoped_ptr<FrameNavExpectationsBrowser>(
|
|
new FrameNavExpectationsBrowserTestNestedIframes(nav, true));
|
|
}
|
|
|
|
private:
|
|
int create_count_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin :
|
|
public FrameNavExpectationsFactoryRenderer {
|
|
public:
|
|
FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_NESTED_IFRAMES_SAME_ORIGIN;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsRenderer>(
|
|
new FrameNavExpectationsRendererTestNestedIframes(nav, true));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Test that nested iframes work.
|
|
FRAME_TEST(NestedIframesSameOrigin, FNF_ID_NESTED_IFRAMES_SAME_ORIGIN)
|
|
|
|
|
|
namespace {
|
|
|
|
class FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin :
|
|
public FrameNavExpectationsFactoryBrowser {
|
|
public:
|
|
FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin()
|
|
: create_count_(0) {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN;
|
|
}
|
|
|
|
bool HasMoreNavigations() const override {
|
|
return (create_count_ < kMaxMultiNavNavigations);
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(create_count_ == kMaxMultiNavNavigations);
|
|
V_RETURN();
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsBrowser> Create(int nav) override {
|
|
create_count_++;
|
|
return make_scoped_ptr<FrameNavExpectationsBrowser>(
|
|
new FrameNavExpectationsBrowserTestNestedIframes(nav, false));
|
|
}
|
|
|
|
private:
|
|
int create_count_;
|
|
};
|
|
|
|
class FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin :
|
|
public FrameNavExpectationsFactoryRenderer {
|
|
public:
|
|
FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin() {}
|
|
|
|
FrameNavFactoryId GetID() const override {
|
|
return FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN;
|
|
}
|
|
|
|
protected:
|
|
scoped_ptr<FrameNavExpectationsRenderer> Create(int nav) override {
|
|
return make_scoped_ptr<FrameNavExpectationsRenderer>(
|
|
new FrameNavExpectationsRendererTestNestedIframes(nav, false));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Test that nested iframes work.
|
|
FRAME_TEST(NestedIframesDiffOrigin, FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN)
|
|
|
|
|
|
namespace {
|
|
|
|
// Returns a new factory in the browser or renderer process. All factory types
|
|
// must be listed here.
|
|
|
|
// static
|
|
scoped_ptr<FrameNavExpectationsFactoryBrowser>
|
|
FrameNavExpectationsFactoryBrowser::FromID(FrameNavFactoryId id) {
|
|
scoped_ptr<FrameNavExpectationsFactoryBrowser> factory;
|
|
switch (id) {
|
|
case FNF_ID_SINGLE_NAV_HARNESS:
|
|
factory.reset(new FrameNavExpectationsFactoryBrowserTestSingleNavHarness);
|
|
break;
|
|
case FNF_ID_SINGLE_NAV:
|
|
factory.reset(new FrameNavExpectationsFactoryBrowserTestSingleNav);
|
|
break;
|
|
case FNF_ID_MULTI_NAV_HARNESS:
|
|
factory.reset(new FrameNavExpectationsFactoryBrowserTestMultiNavHarness);
|
|
break;
|
|
case FNF_ID_MULTI_NAV:
|
|
factory.reset(new FrameNavExpectationsFactoryBrowserTestMultiNav);
|
|
break;
|
|
case FNF_ID_NESTED_IFRAMES_SAME_ORIGIN:
|
|
factory.reset(
|
|
new FrameNavExpectationsFactoryBrowserTestNestedIframesSameOrigin);
|
|
break;
|
|
case FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN:
|
|
factory.reset(
|
|
new FrameNavExpectationsFactoryBrowserTestNestedIframesDiffOrigin);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
EXPECT_TRUE(factory);
|
|
EXPECT_EQ(id, factory->GetID());
|
|
return factory.Pass();
|
|
}
|
|
|
|
// static
|
|
scoped_ptr<FrameNavExpectationsFactoryRenderer>
|
|
FrameNavExpectationsFactoryRenderer::FromID(FrameNavFactoryId id) {
|
|
scoped_ptr<FrameNavExpectationsFactoryRenderer> factory;
|
|
switch (id) {
|
|
case FNF_ID_SINGLE_NAV_HARNESS:
|
|
factory.reset(
|
|
new FrameNavExpectationsFactoryRendererTestSingleNavHarness);
|
|
break;
|
|
case FNF_ID_SINGLE_NAV:
|
|
factory.reset(new FrameNavExpectationsFactoryRendererTestSingleNav);
|
|
break;
|
|
case FNF_ID_MULTI_NAV_HARNESS:
|
|
factory.reset(new FrameNavExpectationsFactoryRendererTestMultiNavHarness);
|
|
break;
|
|
case FNF_ID_MULTI_NAV:
|
|
factory.reset(new FrameNavExpectationsFactoryRendererTestMultiNav);
|
|
break;
|
|
case FNF_ID_NESTED_IFRAMES_SAME_ORIGIN:
|
|
factory.reset(
|
|
new FrameNavExpectationsFactoryRendererTestNestedIframesSameOrigin);
|
|
break;
|
|
case FNF_ID_NESTED_IFRAMES_DIFF_ORIGIN:
|
|
factory.reset(
|
|
new FrameNavExpectationsFactoryRendererTestNestedIframesDiffOrigin);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
EXPECT_TRUE(factory);
|
|
EXPECT_EQ(id, factory->GetID());
|
|
return factory.Pass();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
|
// Entry point for creating frame browser test objects.
|
|
// Called from client_app_delegates.cc.
|
|
void CreateFrameBrowserTests(ClientApp::BrowserDelegateSet& delegates) {
|
|
delegates.insert(new FrameNavBrowserTest);
|
|
}
|
|
|
|
// Entry point for creating frame renderer test objects.
|
|
// Called from client_app_delegates.cc.
|
|
void CreateFrameRendererTests(ClientApp::RenderDelegateSet& delegates) {
|
|
delegates.insert(new FrameNavRendererTest);
|
|
}
|