2355 lines
74 KiB
C++
2355 lines
74 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 "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 "tests/ceftests/test_handler.h"
|
|
#include "tests/ceftests/test_util.h"
|
|
#include "tests/gtest/include/gtest/gtest.h"
|
|
#include "tests/shared/browser/client_app_browser.h"
|
|
#include "tests/shared/renderer/client_app_renderer.h"
|
|
|
|
using client::ClientAppBrowser;
|
|
using client::ClientAppRenderer;
|
|
|
|
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/";
|
|
const char kFrameNavOrigin3[] = "http://tests-framenav3.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 = 4;
|
|
|
|
// 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>, CefRefPtr<CefFrame>)>
|
|
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,
|
|
CefRefPtr<CefFrame> frame) {
|
|
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, frame));
|
|
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 abstract 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) {
|
|
EXPECT_TRUE(browser.get());
|
|
return true;
|
|
}
|
|
virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const std::string& url) {
|
|
EXPECT_TRUE(browser.get());
|
|
EXPECT_TRUE(frame.get());
|
|
EXPECT_FALSE(url.empty());
|
|
return true;
|
|
}
|
|
virtual bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) {
|
|
EXPECT_TRUE(browser.get());
|
|
EXPECT_TRUE(frame.get());
|
|
return true;
|
|
}
|
|
|
|
// Called when the renderer signals completion.
|
|
virtual bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
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) {}
|
|
};
|
|
|
|
// 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 ClientAppBrowser::Delegate {
|
|
public:
|
|
FrameNavBrowserTest() {}
|
|
|
|
void OnBeforeChildProcessLaunch(
|
|
CefRefPtr<ClientAppBrowser> 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 ClientAppRenderer::Delegate,
|
|
public CefLoadHandler {
|
|
public:
|
|
FrameNavRendererTest() : run_test_(false), nav_(0) {}
|
|
|
|
void OnRenderThreadCreated(CefRefPtr<ClientAppRenderer> 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<ClientAppRenderer> 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,
|
|
TransitionType transition_type) 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_;
|
|
}
|
|
|
|
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,
|
|
CefRefPtr<CefFrame> frame) {
|
|
// 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));
|
|
frame->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)) {
|
|
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());
|
|
|
|
// Time out the test after a reasonable period of time.
|
|
SetTestTimeout(15000);
|
|
}
|
|
|
|
// Transition to the next navigation.
|
|
// Will be called via FrameNavExpectations::SignalComplete.
|
|
void RunNextNav(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
|
|
// 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 user_gesture,
|
|
bool is_redirect) override {
|
|
EXPECT_TRUE(
|
|
expectations_->OnBeforeBrowse(browser, frame, request->GetURL()))
|
|
<< "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,
|
|
TransitionType transition_type) 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,
|
|
CefRefPtr<CefFrame> frame,
|
|
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, frame, 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();
|
|
|
|
// 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_;
|
|
|
|
IMPLEMENT_REFCOUNTING(FrameNavTestHandler);
|
|
};
|
|
|
|
// Helper for defining frame tests.
|
|
#define FRAME_TEST(name, factory_id) \
|
|
TEST(FrameTest, name) { \
|
|
CefRefPtr<FrameNavTestHandler> handler = \
|
|
new FrameNavTestHandler(factory_id); \
|
|
handler->ExecuteTest(); \
|
|
ReleaseAndWaitForDestructor(handler); \
|
|
}
|
|
|
|
// 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, browser->GetMainFrame());
|
|
}
|
|
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, frame);
|
|
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,
|
|
const std::string& url) 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,
|
|
CefRefPtr<CefFrame> frame,
|
|
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, frame);
|
|
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,
|
|
CefRefPtr<CefFrame> frame) {
|
|
if (got_renderer_done_ && got_load_end_ && got_loading_state_change_end_)
|
|
SignalComplete(browser, frame);
|
|
}
|
|
|
|
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, browser->GetMainFrame());
|
|
}
|
|
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, frame);
|
|
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_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) {
|
|
if (got_load_end_ && got_loading_state_change_end_)
|
|
SignalComplete(browser, frame);
|
|
}
|
|
|
|
TrackCallback got_load_start_;
|
|
TrackCallback got_load_end_;
|
|
TrackCallback got_loading_state_change_start_;
|
|
TrackCallback got_loading_state_change_end_;
|
|
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 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 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,
|
|
const std::string& expected_url) {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(frame.get());
|
|
V_EXPECT_TRUE(frame->IsValid());
|
|
const int64 frame_id = frame->GetIdentifier();
|
|
V_EXPECT_TRUE(frame_id > 0) << frame_id;
|
|
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,
|
|
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, expected_url));
|
|
}
|
|
|
|
CefRefPtr<CefFrame> main_frame = browser->GetMainFrame();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, main_frame, expected_url));
|
|
|
|
CefRefPtr<CefFrame> focused_frame = browser->GetFocusedFrame();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrame(browser, focused_frame, expected_url));
|
|
|
|
size_t frame_count = browser->GetFrameCount();
|
|
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());
|
|
}
|
|
|
|
// Names may be empty for callbacks that execute while the frame is loading.
|
|
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());
|
|
}
|
|
|
|
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();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(
|
|
browser, NULL, isLoading ? std::string() : 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, 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, kFrameNavOrigin0));
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, std::string()));
|
|
V_EXPECT_TRUE(parent::OnAfterCreated(browser));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const std::string& url) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, std::string()));
|
|
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, std::string()));
|
|
V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
return parent::OnRendererComplete(browser, frame, 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.
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, 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, 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, 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 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 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, browser->GetMainFrame());
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
SignalCompleteIfDone(browser, frame);
|
|
return true;
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
int renderer_nav,
|
|
bool renderer_result) override {
|
|
EXPECT_TRUE(renderer_result);
|
|
SignalCompleteIfDone(browser, frame);
|
|
return true;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) {
|
|
if (IsNavigationDone())
|
|
SignalComplete(browser, frame);
|
|
}
|
|
|
|
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, browser->GetMainFrame());
|
|
return true;
|
|
}
|
|
|
|
bool OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) override {
|
|
SignalCompleteIfDone(browser, frame);
|
|
return true;
|
|
}
|
|
|
|
bool Finalize() override {
|
|
V_DECLARE();
|
|
V_EXPECT_FALSE(got_finalize_);
|
|
|
|
got_finalize_.yes();
|
|
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
void SignalCompleteIfDone(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame) {
|
|
if (IsNavigationDone())
|
|
SignalComplete(browser, frame);
|
|
}
|
|
|
|
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,
|
|
CefRefPtr<CefFrame> frame,
|
|
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, frame, 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 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 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();
|
|
if (isLoading && nav() == 0) {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, std::string()));
|
|
} else if (isLoading) {
|
|
// Expect the URL from the previous load.
|
|
V_EXPECT_TRUE(
|
|
VerifySingleBrowserFrames(browser, NULL, GetPreviousMainURL()));
|
|
} else {
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, 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, 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, GetMainURL()));
|
|
V_EXPECT_TRUE(parent::OnLoadEnd(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, std::string()));
|
|
V_EXPECT_TRUE(parent::OnAfterCreated(browser));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const std::string& url) override {
|
|
V_DECLARE();
|
|
std::string expected_url;
|
|
if (nav() > 0)
|
|
expected_url = GetPreviousMainURL();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, frame, expected_url));
|
|
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
|
|
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, expected_url));
|
|
V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
|
|
V_RETURN();
|
|
}
|
|
|
|
bool OnRendererComplete(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
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, frame, 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();
|
|
V_EXPECT_TRUE(VerifySingleBrowserFrames(browser, NULL, 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, 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, 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 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 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-->-->";
|
|
const char kFrame3Name[] = "nav3";
|
|
|
|
bool VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const std::string& origin,
|
|
int frame_number) {
|
|
V_DECLARE();
|
|
|
|
// frame0 contains frame1 contains frame2, contains frame3.
|
|
CefRefPtr<CefFrame> frame0, frame1, frame2, frame3;
|
|
CefRefPtr<CefFrame> frame0b, frame1b, frame2b, frame3b;
|
|
int64 frame0id, frame1id, frame2id, frame3id;
|
|
std::string frame0url, frame1url, frame2url, frame3url;
|
|
|
|
// Verify the GetFrameNames result.
|
|
std::set<std::string> expected_names = {kFrame0Name, kFrame1Name, kFrame2Name,
|
|
kFrame3Name};
|
|
|
|
std::vector<CefString> names;
|
|
browser->GetFrameNames(names);
|
|
V_EXPECT_TRUE(names.size() == expected_names.size())
|
|
<< "expected: " << expected_names.size() << " actual: " << names.size();
|
|
|
|
for (const auto& name : names) {
|
|
const std::string& nameStr = name;
|
|
auto it = expected_names.find(nameStr);
|
|
V_EXPECT_FALSE(it == expected_names.end())
|
|
<< "Unexpected name: \"" << nameStr << "\"";
|
|
if (it != expected_names.end())
|
|
expected_names.erase(it);
|
|
}
|
|
|
|
for (const auto& name : expected_names) {
|
|
V_EXPECT_FALSE(true) << "Missing name: \"" << name << "\"";
|
|
}
|
|
|
|
// 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());
|
|
frame3 = browser->GetFrame(kFrame3Name);
|
|
V_EXPECT_TRUE(frame3.get());
|
|
|
|
if (!frame0 || !frame1 || !frame2 || !frame3) {
|
|
V_RETURN();
|
|
}
|
|
|
|
// Verify that the name matches.
|
|
V_EXPECT_TRUE(frame0->GetName().ToString() == kFrame0Name)
|
|
<< "expected: " << kFrame0Name
|
|
<< " actual: " << frame0->GetName().ToString();
|
|
V_EXPECT_TRUE(frame1->GetName().ToString() == kFrame1Name)
|
|
<< "expected: " << kFrame1Name
|
|
<< " actual: " << frame1->GetName().ToString();
|
|
V_EXPECT_TRUE(frame2->GetName().ToString() == kFrame2Name)
|
|
<< "expected: " << kFrame2Name
|
|
<< " actual: " << frame2->GetName().ToString();
|
|
V_EXPECT_TRUE(frame3->GetName().ToString() == kFrame3Name)
|
|
<< "expected: " << kFrame3Name
|
|
<< " actual: " << frame3->GetName().ToString();
|
|
|
|
// Verify that the URL matches.
|
|
frame0url = GetMultiNavURL(origin, 0);
|
|
V_EXPECT_TRUE(frame0->GetURL() == frame0url)
|
|
<< "expected: " << frame0url
|
|
<< " actual: " << frame0->GetURL().ToString();
|
|
frame1url = GetMultiNavURL(origin, 1);
|
|
V_EXPECT_TRUE(frame1->GetURL() == frame1url)
|
|
<< "expected: " << frame1url
|
|
<< " actual: " << frame1->GetURL().ToString();
|
|
frame2url = GetMultiNavURL(origin, 2);
|
|
V_EXPECT_TRUE(frame2->GetURL() == frame2url)
|
|
<< "expected: " << frame2url
|
|
<< " actual: " << frame2->GetURL().ToString();
|
|
frame3url = GetMultiNavURL(origin, 3);
|
|
V_EXPECT_TRUE(frame3->GetURL() == frame3url)
|
|
<< "expected: " << frame3url
|
|
<< " actual: " << frame3->GetURL().ToString();
|
|
|
|
// Verify that the frame id is valid.
|
|
frame0id = frame0->GetIdentifier();
|
|
V_EXPECT_TRUE(frame0id > 0) << "actual: " << frame0id;
|
|
frame1id = frame1->GetIdentifier();
|
|
V_EXPECT_TRUE(frame1id > 0) << "actual: " << frame1id;
|
|
frame2id = frame2->GetIdentifier();
|
|
V_EXPECT_TRUE(frame2id > 0) << "actual: " << frame2id;
|
|
frame3id = frame3->GetIdentifier();
|
|
V_EXPECT_TRUE(frame3id > 0) << "actual: " << frame3id;
|
|
|
|
// Verify that the current frame has the correct id.
|
|
if (frame_number == 0) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame0id)
|
|
<< "expected: " << frame0id << " actual: " << frame->GetIdentifier();
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame1id)
|
|
<< "expected: " << frame1id << " actual: " << frame->GetIdentifier();
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame2id)
|
|
<< "expected: " << frame2id << " actual: " << frame->GetIdentifier();
|
|
} else if (frame_number == 3) {
|
|
V_EXPECT_TRUE(frame->GetIdentifier() == frame3id)
|
|
<< "expected: " << frame3id << " actual: " << frame->GetIdentifier();
|
|
}
|
|
|
|
// 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());
|
|
frame3b = browser->GetFrame(frame3->GetIdentifier());
|
|
V_EXPECT_TRUE(frame3b.get());
|
|
|
|
if (!frame0b || !frame1b || !frame2b || !frame3b) {
|
|
V_RETURN();
|
|
}
|
|
|
|
// Verify that the id matches.
|
|
V_EXPECT_TRUE(frame0b->GetIdentifier() == frame0id)
|
|
<< "expected: " << frame0id << " actual: " << frame0b->GetIdentifier();
|
|
V_EXPECT_TRUE(frame1b->GetIdentifier() == frame1id)
|
|
<< "expected: " << frame1id << " actual: " << frame1b->GetIdentifier();
|
|
V_EXPECT_TRUE(frame2b->GetIdentifier() == frame2id)
|
|
<< "expected: " << frame2id << " actual: " << frame2b->GetIdentifier();
|
|
V_EXPECT_TRUE(frame3b->GetIdentifier() == frame3id)
|
|
<< "expected: " << frame3id << " actual: " << frame3b->GetIdentifier();
|
|
|
|
size_t frame_count = browser->GetFrameCount();
|
|
V_EXPECT_TRUE(frame_count == 4U) << " actual: " << frame_count;
|
|
|
|
// Verify the GetFrameIdentifiers result.
|
|
std::set<int64> expected_idents = {frame0id, frame1id, frame2id, frame3id};
|
|
|
|
std::vector<int64> idents;
|
|
browser->GetFrameIdentifiers(idents);
|
|
V_EXPECT_TRUE(idents.size() == expected_idents.size())
|
|
<< "expected: " << expected_idents.size() << " actual: " << idents.size();
|
|
|
|
for (const auto& ident : idents) {
|
|
auto it = expected_idents.find(ident);
|
|
V_EXPECT_FALSE(it == expected_idents.end()) << "Unexpected id: " << ident;
|
|
if (it != expected_idents.end())
|
|
expected_idents.erase(it);
|
|
}
|
|
|
|
for (const auto& ident : expected_idents) {
|
|
V_EXPECT_FALSE(true) << "Missing id: " << ident;
|
|
}
|
|
|
|
// Verify parent hierarchy.
|
|
V_EXPECT_FALSE(frame0->GetParent().get());
|
|
V_EXPECT_TRUE(frame1->GetParent()->GetIdentifier() == frame0id)
|
|
<< "expected: " << frame0id
|
|
<< " actual: " << frame1->GetParent()->GetIdentifier();
|
|
V_EXPECT_TRUE(frame2->GetParent()->GetIdentifier() == frame1id)
|
|
<< "expected: " << frame1id
|
|
<< " actual: " << frame2->GetParent()->GetIdentifier();
|
|
V_EXPECT_TRUE(frame3->GetParent()->GetIdentifier() == frame2id)
|
|
<< "expected: " << frame2id
|
|
<< " actual: " << frame3->GetParent()->GetIdentifier();
|
|
|
|
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;
|
|
case 3:
|
|
origin_ = kFrameNavOrigin3;
|
|
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. Contains an named iframe created via javascript.
|
|
std::stringstream ss;
|
|
ss << "<html><script>"
|
|
<< " function createFrame() {"
|
|
<< " var f = document.createElement('iframe');"
|
|
<< " f.name = 'nav3';"
|
|
<< " f.src = '" << GetMultiNavURL(origin_, 3) << "';"
|
|
<< " document.body.appendChild(f);"
|
|
<< " }</script><body onload=\"createFrame()\">Nav3</body></html>";
|
|
return ss.str();
|
|
}
|
|
case 3:
|
|
// Frame 3.
|
|
return "<html><body>Nav4</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] &&
|
|
got_load_end_[3];
|
|
}
|
|
|
|
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const std::string& url) override {
|
|
V_DECLARE();
|
|
V_EXPECT_TRUE(frame.get());
|
|
const int frame_number = GetNavFromMultiNavURL(url);
|
|
if (frame_number == 0) {
|
|
// Main frame.
|
|
V_EXPECT_TRUE(frame->IsMain());
|
|
} else {
|
|
// Sub frame.
|
|
V_EXPECT_FALSE(frame->IsMain());
|
|
}
|
|
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
|
|
V_RETURN();
|
|
}
|
|
|
|
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]);
|
|
V_EXPECT_FALSE(got_load_start_[3]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_FALSE(got_load_start_[2]);
|
|
V_EXPECT_FALSE(got_load_start_[3]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
V_EXPECT_FALSE(got_load_start_[3]);
|
|
} else if (frame_number == 3) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
V_EXPECT_TRUE(got_load_start_[2]);
|
|
} else {
|
|
V_EXPECT_TRUE(false); // Not reached.
|
|
}
|
|
|
|
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]);
|
|
V_EXPECT_TRUE(got_load_end_[3]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
V_EXPECT_TRUE(got_load_end_[3]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_FALSE(got_load_end_[1]);
|
|
V_EXPECT_TRUE(got_load_end_[3]);
|
|
} else if (frame_number == 3) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_FALSE(got_load_end_[1]);
|
|
V_EXPECT_FALSE(got_load_end_[2]);
|
|
} else {
|
|
V_EXPECT_TRUE(false); // Not reached.
|
|
}
|
|
|
|
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,
|
|
CefRefPtr<CefFrame> frame,
|
|
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, frame, 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_start_[3]);
|
|
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_load_end_[3]);
|
|
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_[4];
|
|
TrackCallback got_load_end_[4];
|
|
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] && got_load_end_[3];
|
|
}
|
|
|
|
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]);
|
|
V_EXPECT_FALSE(got_load_start_[3]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_FALSE(got_load_start_[2]);
|
|
V_EXPECT_FALSE(got_load_start_[3]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
V_EXPECT_FALSE(got_load_start_[3]);
|
|
} else if (frame_number == 3) {
|
|
V_EXPECT_TRUE(got_load_start_[0]);
|
|
V_EXPECT_TRUE(got_load_start_[1]);
|
|
V_EXPECT_TRUE(got_load_start_[2]);
|
|
}
|
|
|
|
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]);
|
|
V_EXPECT_TRUE(got_load_end_[3]);
|
|
} else if (frame_number == 1) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_TRUE(got_load_end_[2]);
|
|
V_EXPECT_TRUE(got_load_end_[3]);
|
|
} else if (frame_number == 2) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_FALSE(got_load_end_[1]);
|
|
V_EXPECT_TRUE(got_load_end_[3]);
|
|
} else if (frame_number == 3) {
|
|
V_EXPECT_FALSE(got_load_end_[0]);
|
|
V_EXPECT_FALSE(got_load_end_[1]);
|
|
V_EXPECT_FALSE(got_load_end_[2]);
|
|
}
|
|
|
|
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_start_[3]);
|
|
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_load_end_[3]);
|
|
V_EXPECT_TRUE(parent::Finalize());
|
|
V_RETURN();
|
|
}
|
|
|
|
private:
|
|
std::string origin_;
|
|
|
|
TrackCallback got_load_state_change_done_;
|
|
TrackCallback got_load_start_[4];
|
|
TrackCallback got_load_end_[4];
|
|
};
|
|
|
|
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 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 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 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 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(ClientAppBrowser::DelegateSet& delegates) {
|
|
delegates.insert(new FrameNavBrowserTest);
|
|
}
|
|
|
|
// Entry point for creating frame renderer test objects.
|
|
// Called from client_app_delegates.cc.
|
|
void CreateFrameRendererTests(ClientAppRenderer::DelegateSet& delegates) {
|
|
delegates.insert(new FrameNavRendererTest);
|
|
}
|