This source file includes following definitions.
- CreateWebUIControllerForURL
- GetWebUIType
- UseWebUIForURL
- UseWebUIBindingsForURL
- UseWebUI
- GetHTMLContents
- delegate_
- OnDontProceed
- OnProceed
- command_received_count
- TestDomOperationResponse
- TestDidNavigate
- TestRenderViewTerminated
- is_showing
- ClearStates
- CommandReceived
- set_delegate
- CreateWebContentsView
- CommandReceived
- OnDontProceed
- OnProceed
- TestInterstitialPageDeleted
- ShouldAssignSiteForURL
- set_assign_site_for_url
- SetUp
- TearDown
- DidFinishLoad
- DidFailLoad
- last_url
- ToggleFullscreenModeForTab
- IsFullscreenForTabOrPending
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- last_zoom_in_
- GetAndResetContentsZoomChangedCallCount
- last_zoom_in
- ContentsZoomChange
- TEST_F
- TEST_F
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/frame_host/cross_site_transferring_request.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/frame_messages.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/view_messages.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
const char kTestWebUIUrl[] = "chrome://blah";
class WebContentsImplTestWebUIControllerFactory
: public WebUIControllerFactory {
public:
virtual WebUIController* CreateWebUIControllerForURL(
WebUI* web_ui, const GURL& url) const OVERRIDE {
if (!UseWebUI(url))
return NULL;
return new WebUIController(web_ui);
}
virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const OVERRIDE {
return WebUI::kNoWebUI;
}
virtual bool UseWebUIForURL(BrowserContext* browser_context,
const GURL& url) const OVERRIDE {
return UseWebUI(url);
}
virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context,
const GURL& url) const OVERRIDE {
return UseWebUI(url);
}
private:
bool UseWebUI(const GURL& url) const {
return url == GURL(kTestWebUIUrl);
}
};
class TestInterstitialPage;
class TestInterstitialPageDelegate : public InterstitialPageDelegate {
public:
explicit TestInterstitialPageDelegate(TestInterstitialPage* interstitial_page)
: interstitial_page_(interstitial_page) {}
virtual void CommandReceived(const std::string& command) OVERRIDE;
virtual std::string GetHTMLContents() OVERRIDE { return std::string(); }
virtual void OnDontProceed() OVERRIDE;
virtual void OnProceed() OVERRIDE;
private:
TestInterstitialPage* interstitial_page_;
};
class TestInterstitialPage : public InterstitialPageImpl {
public:
enum InterstitialState {
INVALID = 0,
UNDECIDED,
OKED,
CANCELED
};
class Delegate {
public:
virtual void TestInterstitialPageDeleted(
TestInterstitialPage* interstitial) = 0;
protected:
virtual ~Delegate() {}
};
TestInterstitialPage(WebContentsImpl* contents,
bool new_navigation,
const GURL& url,
InterstitialState* state,
bool* deleted)
: InterstitialPageImpl(
contents,
static_cast<RenderWidgetHostDelegate*>(contents),
new_navigation, url, new TestInterstitialPageDelegate(this)),
state_(state),
deleted_(deleted),
command_received_count_(0),
delegate_(NULL) {
*state_ = UNDECIDED;
*deleted_ = false;
}
virtual ~TestInterstitialPage() {
if (deleted_)
*deleted_ = true;
if (delegate_)
delegate_->TestInterstitialPageDeleted(this);
}
void OnDontProceed() {
if (state_)
*state_ = CANCELED;
}
void OnProceed() {
if (state_)
*state_ = OKED;
}
int command_received_count() const {
return command_received_count_;
}
void TestDomOperationResponse(const std::string& json_string) {
if (enabled())
CommandReceived();
}
void TestDidNavigate(int page_id, const GURL& url) {
FrameHostMsg_DidCommitProvisionalLoad_Params params;
InitNavigateParams(¶ms, page_id, url, PAGE_TRANSITION_TYPED);
DidNavigate(GetRenderViewHostForTesting(), params);
}
void TestRenderViewTerminated(base::TerminationStatus status,
int error_code) {
RenderViewTerminated(GetRenderViewHostForTesting(), status, error_code);
}
bool is_showing() const {
return static_cast<TestRenderWidgetHostView*>(
GetRenderViewHostForTesting()->GetView())->is_showing();
}
void ClearStates() {
state_ = NULL;
deleted_ = NULL;
delegate_ = NULL;
}
void CommandReceived() {
command_received_count_++;
}
void set_delegate(Delegate* delegate) {
delegate_ = delegate;
}
protected:
virtual WebContentsView* CreateWebContentsView() OVERRIDE {
return NULL;
}
private:
InterstitialState* state_;
bool* deleted_;
int command_received_count_;
Delegate* delegate_;
};
void TestInterstitialPageDelegate::CommandReceived(const std::string& command) {
interstitial_page_->CommandReceived();
}
void TestInterstitialPageDelegate::OnDontProceed() {
interstitial_page_->OnDontProceed();
}
void TestInterstitialPageDelegate::OnProceed() {
interstitial_page_->OnProceed();
}
class TestInterstitialPageStateGuard : public TestInterstitialPage::Delegate {
public:
explicit TestInterstitialPageStateGuard(
TestInterstitialPage* interstitial_page)
: interstitial_page_(interstitial_page) {
DCHECK(interstitial_page_);
interstitial_page_->set_delegate(this);
}
virtual ~TestInterstitialPageStateGuard() {
if (interstitial_page_)
interstitial_page_->ClearStates();
}
virtual void TestInterstitialPageDeleted(
TestInterstitialPage* interstitial) OVERRIDE {
DCHECK(interstitial_page_ == interstitial);
interstitial_page_ = NULL;
}
private:
TestInterstitialPage* interstitial_page_;
};
class WebContentsImplTestBrowserClient : public TestContentBrowserClient {
public:
WebContentsImplTestBrowserClient()
: assign_site_for_url_(false) {}
virtual ~WebContentsImplTestBrowserClient() {}
virtual bool ShouldAssignSiteForURL(const GURL& url) OVERRIDE {
return assign_site_for_url_;
}
void set_assign_site_for_url(bool assign) {
assign_site_for_url_ = assign;
}
private:
bool assign_site_for_url_;
};
class WebContentsImplTest : public RenderViewHostImplTestHarness {
public:
virtual void SetUp() {
RenderViewHostImplTestHarness::SetUp();
WebUIControllerFactory::RegisterFactory(&factory_);
}
virtual void TearDown() {
WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
RenderViewHostImplTestHarness::TearDown();
}
private:
WebContentsImplTestWebUIControllerFactory factory_;
};
class TestWebContentsObserver : public WebContentsObserver {
public:
explicit TestWebContentsObserver(WebContents* contents)
: WebContentsObserver(contents) {
}
virtual ~TestWebContentsObserver() {}
virtual void DidFinishLoad(int64 frame_id,
const GURL& validated_url,
bool is_main_frame,
RenderViewHost* render_view_host) OVERRIDE {
last_url_ = validated_url;
}
virtual void DidFailLoad(int64 frame_id,
const GURL& validated_url,
bool is_main_frame,
int error_code,
const base::string16& error_description,
RenderViewHost* render_view_host) OVERRIDE {
last_url_ = validated_url;
}
const GURL& last_url() const { return last_url_; }
private:
GURL last_url_;
DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver);
};
class FakeFullscreenDelegate : public WebContentsDelegate {
public:
FakeFullscreenDelegate() : fullscreened_contents_(NULL) {}
virtual ~FakeFullscreenDelegate() {}
virtual void ToggleFullscreenModeForTab(WebContents* web_contents,
bool enter_fullscreen) OVERRIDE {
fullscreened_contents_ = enter_fullscreen ? web_contents : NULL;
}
virtual bool IsFullscreenForTabOrPending(const WebContents* web_contents)
const OVERRIDE {
return fullscreened_contents_ && web_contents == fullscreened_contents_;
}
private:
WebContents* fullscreened_contents_;
DISALLOW_COPY_AND_ASSIGN(FakeFullscreenDelegate);
};
}
TEST_F(WebContentsImplTest, UpdateTitle) {
NavigationControllerImpl& cont =
static_cast<NavigationControllerImpl&>(controller());
FrameHostMsg_DidCommitProvisionalLoad_Params params;
InitNavigateParams(¶ms, 0, GURL(kAboutBlankURL), PAGE_TRANSITION_TYPED);
LoadCommittedDetails details;
cont.RendererDidNavigate(main_test_rfh(), params, &details);
contents()->UpdateTitle(rvh(), 0,
base::ASCIIToUTF16(" Lots O' Whitespace\n"),
base::i18n::LEFT_TO_RIGHT);
EXPECT_EQ(base::ASCIIToUTF16("Lots O' Whitespace"), contents()->GetTitle());
}
TEST_F(WebContentsImplTest, DontUseTitleFromPendingEntry) {
const GURL kGURL("chrome://blah");
controller().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_EQ(base::string16(), contents()->GetTitle());
}
TEST_F(WebContentsImplTest, UseTitleFromPendingEntryIfSet) {
const GURL kGURL("chrome://blah");
const base::string16 title = base::ASCIIToUTF16("My Title");
controller().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_EQ(kGURL, entry->GetURL());
entry->SetTitle(title);
EXPECT_EQ(title, contents()->GetTitle());
}
TEST_F(WebContentsImplTest, NTPViewSource) {
NavigationControllerImpl& cont =
static_cast<NavigationControllerImpl&>(controller());
const char kUrl[] = "view-source:chrome://blah";
const GURL kGURL(kUrl);
process()->sink().ClearMessages();
cont.LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
rvh()->GetDelegate()->RenderViewCreated(rvh());
EXPECT_TRUE(process()->sink().GetFirstMessageMatching(
ViewMsg_EnableViewSourceMode::ID));
FrameHostMsg_DidCommitProvisionalLoad_Params params;
InitNavigateParams(¶ms, 0, kGURL, PAGE_TRANSITION_TYPED);
LoadCommittedDetails details;
cont.RendererDidNavigate(main_test_rfh(), params, &details);
EXPECT_EQ(base::ASCIIToUTF16(kUrl), contents()->GetTitle());
}
TEST_F(WebContentsImplTest, UpdateMaxPageID) {
SiteInstance* instance1 = contents()->GetSiteInstance();
scoped_refptr<SiteInstance> instance2(SiteInstance::Create(NULL));
EXPECT_EQ(-1, contents()->GetMaxPageID());
EXPECT_EQ(-1, contents()->GetMaxPageIDForSiteInstance(instance1));
EXPECT_EQ(-1, contents()->GetMaxPageIDForSiteInstance(instance2.get()));
contents()->UpdateMaxPageID(3);
contents()->UpdateMaxPageID(1);
EXPECT_EQ(3, contents()->GetMaxPageID());
EXPECT_EQ(3, contents()->GetMaxPageIDForSiteInstance(instance1));
EXPECT_EQ(-1, contents()->GetMaxPageIDForSiteInstance(instance2.get()));
contents()->UpdateMaxPageIDForSiteInstance(instance2.get(), 7);
EXPECT_EQ(3, contents()->GetMaxPageID());
EXPECT_EQ(3, contents()->GetMaxPageIDForSiteInstance(instance1));
EXPECT_EQ(7, contents()->GetMaxPageIDForSiteInstance(instance2.get()));
}
TEST_F(WebContentsImplTest, SimpleNavigation) {
TestRenderViewHost* orig_rvh = test_rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(instance1, orig_rvh->GetSiteInstance());
EXPECT_TRUE(
NavigationEntryImpl::FromNavigationEntry(controller().GetVisibleEntry())->
site_instance() == NULL);
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(instance1, orig_rvh->GetSiteInstance());
EXPECT_EQ(
instance1,
NavigationEntryImpl::FromNavigationEntry(controller().GetVisibleEntry())->
site_instance());
}
TEST_F(WebContentsImplTest, NavigateToExcessivelyLongURL) {
const GURL url(std::string("http://example.org/").append(
GetMaxURLChars() + 1, 'a'));
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_GENERATED, std::string());
EXPECT_TRUE(controller().GetVisibleEntry() == NULL);
}
TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
RenderFrameHostImpl* orig_rfh =
contents()->GetFrameTree()->root()->current_frame_host();
int orig_rvh_delete_count = 0;
orig_rvh->set_delete_counter(&orig_rvh_delete_count);
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
static_cast<SiteInstanceImpl*>(orig_rvh->GetSiteInstance())->
increment_active_view_count();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
EXPECT_EQ(url, contents()->GetVisibleURL());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
TestRenderViewHost* pending_rvh =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
int pending_rvh_delete_count = 0;
pending_rvh->set_delete_counter(&pending_rvh_delete_count);
RenderFrameHostImpl* pending_rfh = contents()->GetFrameTree()->root()->
render_manager()->pending_frame_host();
EXPECT_TRUE(pending_rvh->are_navigations_suspended());
orig_rvh->SendBeforeUnloadACK(true);
EXPECT_FALSE(pending_rvh->are_navigations_suspended());
contents()->TestDidNavigate(
pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
SiteInstance* instance2 = contents()->GetSiteInstance();
static_cast<SiteInstanceImpl*>(pending_rvh->GetSiteInstance())->
increment_active_view_count();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(url2, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
EXPECT_TRUE(contents()->GetRenderManagerForTesting()->IsOnSwappedOutList(
orig_rfh));
EXPECT_EQ(orig_rvh_delete_count, 0);
controller().GoBack();
TestRenderViewHost* goback_rvh =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
EXPECT_EQ(orig_rvh, goback_rvh);
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_TRUE(goback_rvh->are_navigations_suspended());
pending_rvh->SendBeforeUnloadACK(true);
EXPECT_FALSE(goback_rvh->are_navigations_suspended());
contents()->TestDidNavigate(
goback_rvh, 1, url2, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(goback_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(instance1, contents()->GetSiteInstance());
EXPECT_TRUE(contents()->GetRenderManagerForTesting()->
IsOnSwappedOutList(pending_rfh));
EXPECT_EQ(pending_rvh_delete_count, 0);
pending_rvh->OnSwappedOut(false);
DeleteContents();
EXPECT_EQ(orig_rvh_delete_count, 1);
EXPECT_EQ(pending_rvh_delete_count, 1);
}
TEST_F(WebContentsImplTest, CrossSiteBoundariesAfterCrash) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
int orig_rvh_delete_count = 0;
orig_rvh->set_delete_counter(&orig_rvh_delete_count);
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
orig_rvh->set_render_view_created(false);
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
RenderViewHost* new_rvh = rvh();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
EXPECT_NE(orig_rvh, new_rvh);
EXPECT_EQ(orig_rvh_delete_count, 1);
contents()->TestDidNavigate(new_rvh, 1, url2, PAGE_TRANSITION_TYPED);
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(new_rvh, rvh());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
DeleteContents();
EXPECT_EQ(orig_rvh_delete_count, 1);
}
TEST_F(WebContentsImplTest, NavigateTwoTabsCrossSite) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
scoped_ptr<TestWebContents> contents2(
TestWebContents::Create(browser_context(), instance1));
contents2->transition_cross_site = true;
contents2->GetController().LoadURL(url, Referrer(),
PAGE_TRANSITION_TYPED,
std::string());
contents2->TestDidNavigate(
contents2->GetRenderViewHost(), 2, url, PAGE_TRANSITION_TYPED);
const GURL url2a("http://www.yahoo.com");
controller().LoadURL(
url2a, Referrer(), PAGE_TRANSITION_TYPED, std::string());
orig_rvh->SendBeforeUnloadACK(true);
TestRenderViewHost* pending_rvh_a =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
contents()->TestDidNavigate(
pending_rvh_a, 1, url2a, PAGE_TRANSITION_TYPED);
SiteInstance* instance2a = contents()->GetSiteInstance();
EXPECT_NE(instance1, instance2a);
const GURL url2b("http://mail.yahoo.com");
contents2->GetController().LoadURL(url2b, Referrer(),
PAGE_TRANSITION_TYPED,
std::string());
TestRenderViewHost* rvh2 =
static_cast<TestRenderViewHost*>(contents2->GetRenderViewHost());
rvh2->SendBeforeUnloadACK(true);
TestRenderViewHost* pending_rvh_b =
static_cast<TestRenderViewHost*>(contents2->GetPendingRenderViewHost());
EXPECT_TRUE(pending_rvh_b != NULL);
EXPECT_TRUE(contents2->cross_navigation_pending());
contents2->TestDidNavigate(
pending_rvh_b, 2, url2b, PAGE_TRANSITION_TYPED);
SiteInstance* instance2b = contents2->GetSiteInstance();
EXPECT_NE(instance1, instance2b);
EXPECT_EQ(instance2a, instance2b);
}
TEST_F(WebContentsImplTest, NavigateDoesNotUseUpSiteInstance) {
WebContentsImplTestBrowserClient browser_client;
SetBrowserClientForTesting(&browser_client);
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
RenderFrameHostImpl* orig_rfh =
contents()->GetFrameTree()->root()->current_frame_host();
int orig_rvh_delete_count = 0;
orig_rvh->set_delete_counter(&orig_rvh_delete_count);
SiteInstanceImpl* orig_instance =
static_cast<SiteInstanceImpl*>(contents()->GetSiteInstance());
browser_client.set_assign_site_for_url(false);
const GURL native_url("non-site-url://stuffandthings");
controller().LoadURL(
native_url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, native_url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(native_url, contents()->GetLastCommittedURL());
EXPECT_EQ(native_url, contents()->GetVisibleURL());
EXPECT_EQ(orig_instance, contents()->GetSiteInstance());
EXPECT_EQ(GURL(), contents()->GetSiteInstance()->GetSiteURL());
EXPECT_FALSE(orig_instance->HasSite());
browser_client.set_assign_site_for_url(true);
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(native_url, contents()->GetLastCommittedURL());
EXPECT_EQ(url, contents()->GetVisibleURL());
EXPECT_FALSE(contents()->GetPendingRenderViewHost());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
static_cast<SiteInstanceImpl*>(orig_rvh->GetSiteInstance())->
increment_active_view_count();
EXPECT_EQ(orig_instance, contents()->GetSiteInstance());
EXPECT_TRUE(
contents()->GetSiteInstance()->GetSiteURL().DomainIs("google.com"));
EXPECT_EQ(url, contents()->GetLastCommittedURL());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
TestRenderViewHost* pending_rvh =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
int pending_rvh_delete_count = 0;
pending_rvh->set_delete_counter(&pending_rvh_delete_count);
EXPECT_TRUE(pending_rvh->are_navigations_suspended());
orig_rvh->SendBeforeUnloadACK(true);
EXPECT_FALSE(pending_rvh->are_navigations_suspended());
contents()->TestDidNavigate(
pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
SiteInstance* new_instance = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(url2, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
EXPECT_NE(new_instance, orig_instance);
EXPECT_FALSE(contents()->GetPendingRenderViewHost());
EXPECT_TRUE(contents()->GetRenderManagerForTesting()->IsOnSwappedOutList(
orig_rfh));
EXPECT_EQ(orig_rvh_delete_count, 0);
orig_rvh->OnSwappedOut(false);
DeleteContents();
EXPECT_EQ(orig_rvh_delete_count, 1);
EXPECT_EQ(pending_rvh_delete_count, 1);
}
TEST_F(WebContentsImplTest, FindOpenerRVHWhenPending) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
orig_rvh->SendBeforeUnloadACK(true);
TestRenderViewHost* pending_rvh =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
int opener_routing_id = contents()->CreateOpenerRenderViews(
pending_rvh->GetSiteInstance());
EXPECT_EQ(pending_rvh->GetRoutingID(), opener_routing_id);
}
TEST_F(WebContentsImplTest, CrossSiteComparesAgainstCurrentPage) {
contents()->transition_cross_site = true;
RenderViewHost* orig_rvh = rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(
orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
scoped_ptr<TestWebContents> contents2(
TestWebContents::Create(browser_context(), instance1));
contents2->transition_cross_site = true;
const GURL url2("http://www.yahoo.com");
contents2->GetController().LoadURL(url2, Referrer(),
PAGE_TRANSITION_TYPED,
std::string());
TestRenderViewHost* rvh2 = static_cast<TestRenderViewHost*>(
contents2->GetRenderViewHost());
EXPECT_FALSE(contents2->cross_navigation_pending());
contents2->TestDidNavigate(rvh2, 2, url2, PAGE_TRANSITION_TYPED);
SiteInstance* instance2 = contents2->GetSiteInstance();
EXPECT_NE(instance1, instance2);
EXPECT_FALSE(contents2->cross_navigation_pending());
contents()->TestDidNavigate(
orig_rvh, 2, url2, PAGE_TRANSITION_TYPED);
SiteInstance* instance3 = contents()->GetSiteInstance();
EXPECT_EQ(instance1, instance3);
EXPECT_FALSE(contents()->cross_navigation_pending());
const GURL url3("http://mail.yahoo.com");
controller().LoadURL(
url3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(contents()->cross_navigation_pending());
contents()->TestDidNavigate(
orig_rvh, 3, url3, PAGE_TRANSITION_TYPED);
SiteInstance* instance4 = contents()->GetSiteInstance();
EXPECT_EQ(instance1, instance4);
}
TEST_F(WebContentsImplTest, CrossSiteUnloadHandlers) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
base::TimeTicks now = base::TimeTicks::Now();
orig_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, false, now, now));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
now = base::TimeTicks::Now();
orig_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
contents()->GetPendingRenderViewHost());
contents()->TestDidNavigate(
pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(pending_rvh, rvh());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
}
TEST_F(WebContentsImplTest, CrossSiteNavigationPreempted) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
base::TimeTicks now = base::TimeTicks::Now();
orig_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
EXPECT_TRUE(contents()->cross_navigation_pending());
orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo"));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, rvh());
EXPECT_EQ(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
}
TEST_F(WebContentsImplTest, CrossSiteNavigationBackPreempted) {
contents()->transition_cross_site = true;
const GURL url1("chrome://blah");
controller().LoadURL(
url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
TestRenderViewHost* ntp_rvh = test_rvh();
contents()->TestDidNavigate(ntp_rvh, 1, url1, PAGE_TRANSITION_TYPED);
NavigationEntry* entry1 = controller().GetLastCommittedEntry();
SiteInstance* instance1 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(ntp_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(url1, entry1->GetURL());
EXPECT_EQ(instance1,
NavigationEntryImpl::FromNavigationEntry(entry1)->site_instance());
EXPECT_TRUE(ntp_rvh->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
const GURL url2("http://www.google.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* google_rvh =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
EXPECT_TRUE(ntp_rvh->is_waiting_for_beforeunload_ack());
base::TimeTicks now = base::TimeTicks::Now();
ntp_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
contents()->TestDidNavigate(
google_rvh, 1, url2, PAGE_TRANSITION_TYPED);
NavigationEntry* entry2 = controller().GetLastCommittedEntry();
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(google_rvh, contents()->GetRenderViewHost());
EXPECT_NE(instance1, instance2);
EXPECT_FALSE(contents()->GetPendingRenderViewHost());
EXPECT_EQ(url2, entry2->GetURL());
EXPECT_EQ(instance2,
NavigationEntryImpl::FromNavigationEntry(entry2)->site_instance());
EXPECT_FALSE(google_rvh->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
const GURL url3("http://news.google.com");
controller().LoadURL(
url3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(contents()->cross_navigation_pending());
contents()->TestDidNavigate(
google_rvh, 2, url3, PAGE_TRANSITION_TYPED);
NavigationEntry* entry3 = controller().GetLastCommittedEntry();
SiteInstance* instance3 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(google_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(instance2, instance3);
EXPECT_FALSE(contents()->GetPendingRenderViewHost());
EXPECT_EQ(url3, entry3->GetURL());
EXPECT_EQ(instance3,
NavigationEntryImpl::FromNavigationEntry(entry3)->site_instance());
controller().GoBack();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(entry2, controller().GetPendingEntry());
controller().GoBack();
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_TRUE(contents()->GetPendingRenderViewHost());
EXPECT_EQ(entry1, controller().GetPendingEntry());
EXPECT_TRUE(google_rvh->is_waiting_for_beforeunload_ack());
now = base::TimeTicks::Now();
google_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
contents()->TestDidNavigate(google_rvh, 1, url2, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_FALSE(controller().GetPendingEntry());
EXPECT_EQ(google_rvh, contents()->GetRenderViewHost());
EXPECT_EQ(url2, controller().GetLastCommittedEntry()->GetURL());
EXPECT_EQ(instance3,
NavigationEntryImpl::FromNavigationEntry(entry3)->site_instance());
EXPECT_EQ(instance2,
NavigationEntryImpl::FromNavigationEntry(entry2)->site_instance());
EXPECT_EQ(instance1,
NavigationEntryImpl::FromNavigationEntry(entry1)->site_instance());
EXPECT_EQ(url1, entry1->GetURL());
}
TEST_F(WebContentsImplTest, CrossSiteNavigationNotPreemptedByFrame) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
orig_rvh->SendNavigateWithTransition(1, GURL("http://google.com/frame"),
PAGE_TRANSITION_AUTO_SUBFRAME);
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
base::TimeTicks now = base::TimeTicks::Now();
orig_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
EXPECT_TRUE(contents()->cross_navigation_pending());
}
TEST_F(WebContentsImplTest, CrossSiteNotPreemptedDuringBeforeUnload) {
contents()->transition_cross_site = true;
const GURL url("chrome://blah");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
TestRenderViewHost* orig_rvh = test_rvh();
EXPECT_FALSE(contents()->cross_navigation_pending());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
TestRenderViewHost* pending_rvh =
static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
orig_rvh->SendNavigate(1, GURL("chrome://blah"));
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
contents()->TestDidNavigate(pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost());
}
TEST_F(WebContentsImplTest, CrossSiteCantPreemptAfterUnload) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
base::TimeTicks now = base::TimeTicks::Now();
orig_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
contents()->GetPendingRenderViewHost());
std::vector<GURL> url_chain;
url_chain.push_back(GURL());
contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
contents()->GetRenderManagerForTesting()->pending_frame_host(),
GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
FrameHostMsg_DidCommitProvisionalLoad_Params params1a;
InitNavigateParams(¶ms1a, 2, GURL("http://www.google.com/foo"),
PAGE_TRANSITION_TYPED);
orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo"));
EXPECT_TRUE(contents()->cross_navigation_pending());
EXPECT_TRUE(contents()->GetPendingRenderViewHost() != NULL);
contents()->TestDidNavigate(
pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(pending_rvh, rvh());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
}
TEST_F(WebContentsImplTest, CrossSiteNavigationCanceled) {
contents()->transition_cross_site = true;
TestRenderViewHost* orig_rvh = test_rvh();
SiteInstance* instance1 = contents()->GetSiteInstance();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
const GURL url2("http://www.yahoo.com");
controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
base::TimeTicks now = base::TimeTicks::Now();
orig_rvh->GetMainFrame()->OnMessageReceived(
FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
EXPECT_TRUE(contents()->cross_navigation_pending());
orig_rvh->OnSwappedOut(false);
controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, rvh());
EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, orig_rvh->rvh_state());
EXPECT_EQ(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
}
TEST_F(WebContentsImplTest, NavigationEntryContentState) {
TestRenderViewHost* orig_rvh = test_rvh();
const GURL url("http://www.google.com");
controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
NavigationEntry* entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry == NULL);
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
const GURL url2("http://images.google.com");
controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
contents()->TestDidNavigate(orig_rvh, 2, url2, PAGE_TRANSITION_TYPED);
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
controller().GoBack();
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
}
TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) {
TestRenderViewHost* orig_rvh = test_rvh();
const GURL url(kAboutBlankURL);
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
NavigationEntry* entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
NavigationEntryImpl* entry_impl =
NavigationEntryImpl::FromNavigationEntry(entry);
EXPECT_FALSE(entry_impl->site_instance()->HasSite());
int32 site_instance_id = entry_impl->site_instance()->GetId();
const GURL new_url("http://www.google.com");
controller().LoadURL(new_url, Referrer(),
PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
contents()->TestDidNavigate(orig_rvh, 1, new_url, PAGE_TRANSITION_TYPED);
NavigationEntryImpl* entry_impl2 = NavigationEntryImpl::FromNavigationEntry(
controller().GetLastCommittedEntry());
EXPECT_EQ(site_instance_id, entry_impl2->site_instance()->GetId());
EXPECT_TRUE(entry_impl2->site_instance()->HasSite());
}
TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
FakeFullscreenDelegate fake_delegate;
contents()->SetDelegate(&fake_delegate);
TestRenderViewHost* orig_rvh = test_rvh();
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
EXPECT_FALSE(orig_rvh->IsFullscreen());
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
orig_rvh->OnMessageReceived(
ViewHostMsg_ToggleFullscreen(orig_rvh->GetRoutingID(), true));
EXPECT_TRUE(orig_rvh->IsFullscreen());
EXPECT_TRUE(contents()->IsFullscreenForCurrentTab());
EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents()));
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
RenderViewHost* const pending_rvh = contents()->GetPendingRenderViewHost();
contents()->TestDidNavigate(
pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(orig_rvh->IsFullscreen());
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
contents()->SetDelegate(NULL);
}
TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
FakeFullscreenDelegate fake_delegate;
contents()->SetDelegate(&fake_delegate);
TestRenderViewHost* const orig_rvh = test_rvh();
const GURL url("http://www.google.com");
controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
const GURL url2("http://www.google.com/search?q=kittens");
controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(contents()->cross_navigation_pending());
contents()->TestDidNavigate(orig_rvh, 2, url2, PAGE_TRANSITION_TYPED);
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
EXPECT_FALSE(orig_rvh->IsFullscreen());
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
for (int i = 0; i < 2; ++i) {
orig_rvh->OnMessageReceived(
ViewHostMsg_ToggleFullscreen(orig_rvh->GetRoutingID(), true));
EXPECT_TRUE(orig_rvh->IsFullscreen());
EXPECT_TRUE(contents()->IsFullscreenForCurrentTab());
EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents()));
if (i == 0)
controller().GoBack();
else
controller().GoForward();
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
contents()->TestDidNavigate(
orig_rvh, i + 1, url, PAGE_TRANSITION_FORWARD_BACK);
EXPECT_FALSE(orig_rvh->IsFullscreen());
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
}
contents()->SetDelegate(NULL);
}
TEST_F(WebContentsImplTest, CrashExitsFullscreen) {
FakeFullscreenDelegate fake_delegate;
contents()->SetDelegate(&fake_delegate);
const GURL url("http://www.google.com");
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(test_rvh(), 1, url, PAGE_TRANSITION_TYPED);
EXPECT_EQ(test_rvh(), contents()->GetRenderViewHost());
EXPECT_FALSE(test_rvh()->IsFullscreen());
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
test_rvh()->OnMessageReceived(
ViewHostMsg_ToggleFullscreen(test_rvh()->GetRoutingID(), true));
EXPECT_TRUE(test_rvh()->IsFullscreen());
EXPECT_TRUE(contents()->IsFullscreenForCurrentTab());
EXPECT_TRUE(fake_delegate.IsFullscreenForTabOrPending(contents()));
test_rvh()->OnMessageReceived(
ViewHostMsg_RenderProcessGone(
0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
EXPECT_FALSE(test_rvh()->IsFullscreen());
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
EXPECT_FALSE(fake_delegate.IsFullscreenForTabOrPending(contents()));
contents()->SetDelegate(NULL);
}
TEST_F(WebContentsImplTest,
ShowInterstitialFromBrowserWithNewNavigationDontProceed) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
controller().LoadURL(GURL("http://www.evil.com"), Referrer(),
PAGE_TRANSITION_TYPED, std::string());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
EXPECT_FALSE(interstitial->is_showing());
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url2);
interstitial->DontProceed();
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url1);
EXPECT_EQ(1, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest,
ShowInterstitiaFromRendererlWithNewNavigationDontProceed) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
EXPECT_FALSE(interstitial->is_showing());
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url2);
interstitial->DontProceed();
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url1);
EXPECT_EQ(1, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialNoNewNavigationDontProceed) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), false, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
EXPECT_FALSE(interstitial->is_showing());
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url1);
interstitial->DontProceed();
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url1);
EXPECT_EQ(1, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest,
ShowInterstitialFromBrowserNewNavigationProceed) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
controller().LoadURL(GURL("http://www.evil.com"), Referrer(),
PAGE_TRANSITION_TYPED, std::string());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
EXPECT_FALSE(interstitial->is_showing());
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url2);
interstitial->Proceed();
RunAllPendingInMessageLoop();
ASSERT_FALSE(deleted);
EXPECT_EQ(TestInterstitialPage::OKED, state);
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
GURL url3("http://www.thepage.com");
test_rvh()->SendNavigate(2, url3);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url3);
EXPECT_EQ(2, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest,
ShowInterstitialFromRendererNewNavigationProceed) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
EXPECT_FALSE(interstitial->is_showing());
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url2);
interstitial->Proceed();
RunAllPendingInMessageLoop();
ASSERT_FALSE(deleted);
EXPECT_EQ(TestInterstitialPage::OKED, state);
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
GURL url3("http://www.thepage.com");
test_rvh()->SendNavigate(2, url3);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url3);
EXPECT_EQ(2, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialNoNewNavigationProceed) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), false, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
EXPECT_FALSE(interstitial->is_showing());
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_TRUE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url1);
interstitial->Proceed();
EXPECT_EQ(TestInterstitialPage::OKED, state);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == url1);
EXPECT_EQ(1, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialThenNavigate) {
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, url);
const GURL url2("http://www.yahoo.com");
test_rvh()->SendNavigate(1, url2);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialThenGoBack) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL interstitial_url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, interstitial_url,
&state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(2, interstitial_url);
controller().GoBack();
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(url1.spec(), entry->GetURL().spec());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenGoBack) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL interstitial_url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, interstitial_url,
&state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(2, interstitial_url);
test_rvh()->OnMessageReceived(
ViewHostMsg_RenderProcessGone(
0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
controller().GoBack();
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(url1.spec(), entry->GetURL().spec());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenNavigate) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL interstitial_url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, interstitial_url,
&state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
test_rvh()->OnMessageReceived(
ViewHostMsg_RenderProcessGone(
0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
interstitial->TestDidNavigate(2, interstitial_url);
}
TEST_F(WebContentsImplTest, ShowInterstitialThenCloseTab) {
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, url);
DeleteContents();
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialThenCloseAndShutdown) {
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, url);
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
interstitial->GetRenderViewHostForTesting());
DeleteContents();
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
rvh->OnMessageReceived(
ViewHostMsg_RenderProcessGone(0, 0, 0));
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, ShowInterstitialProceedMultipleCommands) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, url2);
EXPECT_EQ(0, interstitial->command_received_count());
interstitial->TestDomOperationResponse("toto");
EXPECT_EQ(1, interstitial->command_received_count());
interstitial->Proceed();
RunAllPendingInMessageLoop();
ASSERT_FALSE(deleted);
interstitial->TestDomOperationResponse("hello");
interstitial->TestDomOperationResponse("hi");
EXPECT_EQ(1, interstitial->command_received_count());
}
TEST_F(WebContentsImplTest, ShowInterstitialOnInterstitial) {
GURL start_url("http://www.google.com");
test_rvh()->SendNavigate(1, start_url);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state1 =
TestInterstitialPage::INVALID;
bool deleted1 = false;
GURL url1("http://interstitial1");
TestInterstitialPage* interstitial1 =
new TestInterstitialPage(contents(), true, url1, &state1, &deleted1);
TestInterstitialPageStateGuard state_guard1(interstitial1);
interstitial1->Show();
interstitial1->TestDidNavigate(1, url1);
TestInterstitialPage::InterstitialState state2 =
TestInterstitialPage::INVALID;
bool deleted2 = false;
GURL url2("http://interstitial2");
TestInterstitialPage* interstitial2 =
new TestInterstitialPage(contents(), true, url2, &state2, &deleted2);
TestInterstitialPageStateGuard state_guard2(interstitial2);
interstitial2->Show();
interstitial2->TestDidNavigate(1, url2);
EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted1);
ASSERT_FALSE(deleted2);
interstitial2->Proceed();
GURL landing_url("http://www.thepage.com");
test_rvh()->SendNavigate(2, landing_url);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == landing_url);
EXPECT_EQ(2, controller().GetEntryCount());
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted2);
}
TEST_F(WebContentsImplTest, ShowInterstitialProceedShowInterstitial) {
GURL start_url("http://www.google.com");
test_rvh()->SendNavigate(1, start_url);
EXPECT_EQ(1, controller().GetEntryCount());
TestInterstitialPage::InterstitialState state1 =
TestInterstitialPage::INVALID;
bool deleted1 = false;
GURL url1("http://interstitial1");
TestInterstitialPage* interstitial1 =
new TestInterstitialPage(contents(), true, url1, &state1, &deleted1);
TestInterstitialPageStateGuard state_guard1(interstitial1);
interstitial1->Show();
interstitial1->TestDidNavigate(1, url1);
interstitial1->Proceed();
EXPECT_EQ(TestInterstitialPage::OKED, state1);
TestInterstitialPage::InterstitialState state2 =
TestInterstitialPage::INVALID;
bool deleted2 = false;
GURL url2("http://interstitial2");
TestInterstitialPage* interstitial2 =
new TestInterstitialPage(contents(), true, url2, &state2, &deleted2);
TestInterstitialPageStateGuard state_guard2(interstitial2);
interstitial2->Show();
interstitial2->TestDidNavigate(1, url2);
EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted1);
ASSERT_FALSE(deleted2);
interstitial2->Proceed();
GURL landing_url("http://www.thepage.com");
test_rvh()->SendNavigate(2, landing_url);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted2);
EXPECT_FALSE(contents()->ShowingInterstitialPage());
EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
NavigationEntry* entry = controller().GetVisibleEntry();
ASSERT_TRUE(entry != NULL);
EXPECT_TRUE(entry->GetURL() == landing_url);
EXPECT_EQ(2, controller().GetEntryCount());
}
TEST_F(WebContentsImplTest, NavigateBeforeInterstitialShows) {
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL interstitial_url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, interstitial_url,
&state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
const GURL url("http://www.google.com");
controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_FALSE(interstitial->is_showing());
RunAllPendingInMessageLoop();
ASSERT_FALSE(deleted);
interstitial->TestDidNavigate(1, interstitial_url);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, TwoQuickInterstitials) {
GURL interstitial_url("http://interstitial");
TestInterstitialPage::InterstitialState state1 =
TestInterstitialPage::INVALID;
bool deleted1 = false;
TestInterstitialPage* interstitial1 =
new TestInterstitialPage(contents(), true, interstitial_url,
&state1, &deleted1);
TestInterstitialPageStateGuard state_guard1(interstitial1);
interstitial1->Show();
TestInterstitialPage::InterstitialState state2 =
TestInterstitialPage::INVALID;
bool deleted2 = false;
TestInterstitialPage* interstitial2 =
new TestInterstitialPage(contents(), true, interstitial_url,
&state2, &deleted2);
TestInterstitialPageStateGuard state_guard2(interstitial2);
interstitial2->Show();
EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted1);
ASSERT_FALSE(deleted2);
interstitial2->TestDidNavigate(1, interstitial_url);
EXPECT_EQ(interstitial2, contents()->GetInterstitialPage());
}
TEST_F(WebContentsImplTest, InterstitialCrasher) {
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestRenderViewTerminated(
base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
interstitial =
new TestInterstitialPage(contents(), true, url, &state, &deleted);
interstitial->Show();
interstitial->TestDidNavigate(1, url);
interstitial->TestRenderViewTerminated(
base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
}
TEST_F(WebContentsImplTest, NewInterstitialDoesNotCancelPendingEntry) {
const char kUrl[] = "http://www.badguys.com/";
const GURL kGURL(kUrl);
contents()->GetController().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, kGURL);
contents()->GetController().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
TestInterstitialPage::InterstitialState state2 =
TestInterstitialPage::INVALID;
bool deleted2 = false;
TestInterstitialPage* interstitial2 =
new TestInterstitialPage(contents(), true, kGURL, &state2, &deleted2);
TestInterstitialPageStateGuard state_guard2(interstitial2);
interstitial2->Show();
interstitial2->TestDidNavigate(1, kGURL);
NavigationEntry* entry = contents()->GetController().GetPendingEntry();
ASSERT_TRUE(entry);
EXPECT_EQ(kUrl, entry->GetURL().spec());
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
RunAllPendingInMessageLoop();
EXPECT_TRUE(deleted);
EXPECT_FALSE(deleted2);
}
TEST_F(WebContentsImplTest, NoJSMessageOnInterstitials) {
const char kUrl[] = "http://www.badguys.com/";
const GURL kGURL(kUrl);
contents()->GetController().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(rvh(), 1, kGURL, PAGE_TRANSITION_TYPED);
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, kGURL);
IPC::Message* dummy_message = new IPC::Message;
bool did_suppress_message = false;
contents()->RunJavaScriptMessage(contents()->GetRenderViewHost(),
base::ASCIIToUTF16("This is an informative message"),
base::ASCIIToUTF16("OK"),
kGURL, JAVASCRIPT_MESSAGE_TYPE_ALERT, dummy_message,
&did_suppress_message);
EXPECT_TRUE(did_suppress_message);
}
TEST_F(WebContentsImplTest, CopyStateFromAndPruneSourceInterstitial) {
GURL url1("http://www.google.com");
test_rvh()->SendNavigate(1, url1);
EXPECT_EQ(1, controller().GetEntryCount());
controller().LoadURL(GURL("http://www.evil.com"), Referrer(),
PAGE_TRANSITION_TYPED, std::string());
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url2("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(contents(), true, url2, &state, &deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, url2);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_EQ(2, controller().GetEntryCount());
GURL url3("http://foo2");
scoped_ptr<TestWebContents> other_contents(
static_cast<TestWebContents*>(CreateTestWebContents()));
NavigationControllerImpl& other_controller = other_contents->GetController();
other_contents->NavigateAndCommit(url3);
other_contents->ExpectSetHistoryLengthAndPrune(
NavigationEntryImpl::FromNavigationEntry(
other_controller.GetEntryAtIndex(0))->site_instance(), 1,
other_controller.GetEntryAtIndex(0)->GetPageID());
other_controller.CopyStateFromAndPrune(&controller(), false);
ASSERT_EQ(2, other_controller.GetEntryCount());
EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
EXPECT_FALSE(other_contents->ShowingInterstitialPage());
}
TEST_F(WebContentsImplTest, CopyStateFromAndPruneTargetInterstitial) {
GURL url1("http://www.google.com");
contents()->NavigateAndCommit(url1);
scoped_ptr<TestWebContents> other_contents(
static_cast<TestWebContents*>(CreateTestWebContents()));
NavigationControllerImpl& other_controller = other_contents->GetController();
GURL url2("http://foo2");
other_contents->NavigateAndCommit(url2);
TestInterstitialPage::InterstitialState state =
TestInterstitialPage::INVALID;
bool deleted = false;
GURL url3("http://interstitial");
TestInterstitialPage* interstitial =
new TestInterstitialPage(other_contents.get(), true, url3, &state,
&deleted);
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
interstitial->TestDidNavigate(1, url3);
EXPECT_TRUE(interstitial->is_showing());
EXPECT_EQ(2, other_controller.GetEntryCount());
EXPECT_FALSE(other_controller.CanPruneAllButLastCommitted());
}
TEST_F(WebContentsImplTest, FilterURLs) {
TestWebContentsObserver observer(contents());
GURL url_normalized(kAboutBlankURL);
GURL url_from_ipc("about:whatever");
contents()->NavigateAndCommit(url_normalized);
contents()->TestDidFinishLoad(url_from_ipc);
EXPECT_EQ(url_normalized, observer.last_url());
scoped_ptr<TestWebContents> other_contents(
static_cast<TestWebContents*>(CreateTestWebContents()));
TestWebContentsObserver other_observer(other_contents.get());
other_contents->NavigateAndCommit(url_normalized);
other_contents->TestDidFailLoadWithError(
url_from_ipc, 1, base::string16());
EXPECT_EQ(url_normalized, other_observer.last_url());
}
TEST_F(WebContentsImplTest, PendingContents) {
scoped_ptr<TestWebContents> other_contents(
static_cast<TestWebContents*>(CreateTestWebContents()));
contents()->AddPendingContents(other_contents.get());
int route_id = other_contents->GetRenderViewHost()->GetRoutingID();
other_contents.reset();
EXPECT_EQ(NULL, contents()->GetCreatedWindow(route_id));
}
TEST_F(WebContentsImplTest, CapturerOverridesPreferredSize) {
const gfx::Size original_preferred_size(1024, 768);
contents()->UpdatePreferredSize(original_preferred_size);
EXPECT_EQ(contents()->GetCapturerCount(), 0);
EXPECT_EQ(original_preferred_size, contents()->GetPreferredSize());
contents()->IncrementCapturerCount(gfx::Size());
EXPECT_EQ(1, contents()->GetCapturerCount());
EXPECT_EQ(gfx::Size(), contents()->GetPreferredSize());
const gfx::Size capture_size(1280, 720);
contents()->IncrementCapturerCount(capture_size);
EXPECT_EQ(2, contents()->GetCapturerCount());
EXPECT_EQ(capture_size, contents()->GetPreferredSize());
const gfx::Size another_capture_size(720, 480);
contents()->IncrementCapturerCount(another_capture_size);
EXPECT_EQ(3, contents()->GetCapturerCount());
EXPECT_EQ(capture_size, contents()->GetPreferredSize());
contents()->DecrementCapturerCount();
contents()->DecrementCapturerCount();
EXPECT_EQ(1, contents()->GetCapturerCount());
EXPECT_EQ(capture_size, contents()->GetPreferredSize());
contents()->DecrementCapturerCount();
EXPECT_EQ(0, contents()->GetCapturerCount());
EXPECT_EQ(original_preferred_size, contents()->GetPreferredSize());
}
TEST_F(WebContentsImplTest, GetLastActiveTime) {
EXPECT_FALSE(contents()->GetLastActiveTime().is_null());
contents()->last_active_time_ = base::TimeTicks();
ASSERT_TRUE(contents()->GetLastActiveTime().is_null());
contents()->WasShown();
EXPECT_FALSE(contents()->GetLastActiveTime().is_null());
}
class ContentsZoomChangedDelegate : public WebContentsDelegate {
public:
ContentsZoomChangedDelegate() :
contents_zoom_changed_call_count_(0),
last_zoom_in_(false) {
}
int GetAndResetContentsZoomChangedCallCount() {
int count = contents_zoom_changed_call_count_;
contents_zoom_changed_call_count_ = 0;
return count;
}
bool last_zoom_in() const {
return last_zoom_in_;
}
virtual void ContentsZoomChange(bool zoom_in) OVERRIDE {
contents_zoom_changed_call_count_++;
last_zoom_in_ = zoom_in;
}
private:
int contents_zoom_changed_call_count_;
bool last_zoom_in_;
DISALLOW_COPY_AND_ASSIGN(ContentsZoomChangedDelegate);
};
TEST_F(WebContentsImplTest, HandleWheelEvent) {
using blink::WebInputEvent;
scoped_ptr<ContentsZoomChangedDelegate> delegate(
new ContentsZoomChangedDelegate());
contents()->SetDelegate(delegate.get());
int modifiers = 0;
float dy = 1;
blink::WebMouseWheelEvent event =
SyntheticWebMouseWheelEventBuilder::Build(0, dy, modifiers, false);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
event = SyntheticWebMouseWheelEventBuilder::Build(0, dy, modifiers, false);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
modifiers = WebInputEvent::ControlKey;
event = SyntheticWebMouseWheelEventBuilder::Build(0, dy, modifiers, false);
bool handled = contents()->HandleWheelEvent(event);
#if defined(OS_MACOSX)
EXPECT_FALSE(handled);
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
#else
EXPECT_TRUE(handled);
EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_TRUE(delegate->last_zoom_in());
#endif
modifiers = WebInputEvent::ControlKey | WebInputEvent::ShiftKey |
WebInputEvent::AltKey;
dy = -5;
event = SyntheticWebMouseWheelEventBuilder::Build(2, dy, modifiers, false);
handled = contents()->HandleWheelEvent(event);
#if defined(OS_MACOSX)
EXPECT_FALSE(handled);
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
#else
EXPECT_TRUE(handled);
EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_FALSE(delegate->last_zoom_in());
#endif
dy = 0;
event = SyntheticWebMouseWheelEventBuilder::Build(2, dy, modifiers, false);
EXPECT_FALSE(contents()->HandleWheelEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
contents()->SetDelegate(NULL);
}
TEST_F(WebContentsImplTest, HandleGestureEvent) {
using blink::WebGestureEvent;
using blink::WebInputEvent;
scoped_ptr<ContentsZoomChangedDelegate> delegate(
new ContentsZoomChangedDelegate());
contents()->SetDelegate(delegate.get());
const float kZoomStepValue = 0.6f;
blink::WebGestureEvent event = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::GesturePinchUpdate, WebGestureEvent::Touchpad);
event.data.pinchUpdate.scale = kZoomStepValue * 0.8f;
EXPECT_TRUE(contents()->HandleGestureEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_TRUE(contents()->HandleGestureEvent(event));
EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_TRUE(delegate->last_zoom_in());
event.data.pinchUpdate.scale = -kZoomStepValue;
EXPECT_TRUE(contents()->HandleGestureEvent(event));
EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_FALSE(delegate->last_zoom_in());
EXPECT_TRUE(contents()->HandleGestureEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_TRUE(contents()->HandleGestureEvent(event));
EXPECT_EQ(1, delegate->GetAndResetContentsZoomChangedCallCount());
EXPECT_FALSE(delegate->last_zoom_in());
event = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::GesturePinchUpdate, WebGestureEvent::Touchscreen);
event.data.pinchUpdate.scale = kZoomStepValue * 3;
EXPECT_FALSE(contents()->HandleGestureEvent(event));
EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount());
contents()->SetDelegate(NULL);
}
}