summaryrefslogtreecommitdiffstats
path: root/chrome/browser/web_contents_unittest.cc
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-17 19:36:52 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-17 19:36:52 +0000
commita0729671be0628b5d2c45ef9c19a51c53bfa65b5 (patch)
tree5e4fadde19f6c5702a799cc3b786fee48fc4c9c0 /chrome/browser/web_contents_unittest.cc
parent39ae0a282dc3c1b9e1aea492e11c4d1439ac6921 (diff)
downloadchromium_src-a0729671be0628b5d2c45ef9c19a51c53bfa65b5.zip
chromium_src-a0729671be0628b5d2c45ef9c19a51c53bfa65b5.tar.gz
chromium_src-a0729671be0628b5d2c45ef9c19a51c53bfa65b5.tar.bz2
Revamp of the interstitial pages.
The interstitial is now a RVH that is displayed on top of the WebContents with no interaction with the WebContents' RenderViewHostManager. This simplifies the states that the RenderViewHostManager has. The interstitial is responsible for hiding and deleting itself when told to proceed/not proceed or when a navigation occurs or the tab is closed. The interstitial now uses a data URL (instead of loading some alternate HTML), which allowed me to remove some interstitial flags from NavigationController::LoadCommittedDetails and ProvisionalLoadDetails. Also changed tab_utils::GetTabContentsByID to return a WebContents since only WebContents have a RVH associated with them. TEST=Run all ui tests and unit tests. Review URL: http://codereview.chromium.org/13764 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7149 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/web_contents_unittest.cc')
-rw-r--r--chrome/browser/web_contents_unittest.cc1261
1 files changed, 604 insertions, 657 deletions
diff --git a/chrome/browser/web_contents_unittest.cc b/chrome/browser/web_contents_unittest.cc
index 4811350..8f9ed31 100644
--- a/chrome/browser/web_contents_unittest.cc
+++ b/chrome/browser/web_contents_unittest.cc
@@ -16,11 +16,29 @@
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
+static void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
+ int page_id,
+ const GURL& url) {
+ params->page_id = page_id;
+ params->url = url;
+ params->referrer = GURL::EmptyGURL();
+ params->transition = PageTransition::TYPED;
+ params->redirects = std::vector<GURL>();
+ params->should_update_history = false;
+ params->searchable_form_url = GURL::EmptyGURL();
+ params->searchable_form_element_name = std::wstring();
+ params->searchable_form_encoding = std::string();
+ params->password_form = PasswordForm();
+ params->security_info = std::string();
+ params->gesture = NavigationGestureUser;
+ params->is_post = false;
+}
+
// Subclass the RenderViewHost's view so that we can call Show(), etc.,
// without having side-effects.
class TestRenderWidgetHostView : public RenderWidgetHostView {
public:
- TestRenderWidgetHostView() {}
+ TestRenderWidgetHostView() : is_showing_(false) {}
virtual RenderWidgetHost* GetRenderWidgetHost() const { return NULL; }
virtual void DidBecomeSelected() {}
@@ -35,8 +53,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void Blur() {}
virtual bool HasFocus() { return true; }
virtual void AdvanceFocus(bool reverse) {}
- virtual void Show() {}
- virtual void Hide() {}
+ virtual void Show() { is_showing_ = true; }
+ virtual void Hide() { is_showing_ = false; }
virtual gfx::Rect GetViewBounds() const { return gfx::Rect(); }
virtual void UpdateCursor(const WebCursor& cursor) {}
virtual void UpdateCursorIfOverSelf() {}
@@ -50,6 +68,11 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void Destroy() {}
virtual void PrepareToDestroy() {}
virtual void SetTooltipText(const std::wstring& tooltip_text) {}
+
+ bool is_showing() const { return is_showing_; }
+
+ private:
+ bool is_showing_;
};
// Subclass RenderViewHost so that it does not create a process.
@@ -184,33 +207,10 @@ class TestWebContents : public WebContents {
return static_cast<TestRenderViewHost*>(
render_manager_.pending_render_view_host_);
}
- TestRenderViewHost* interstitial_rvh() {
- return static_cast<TestRenderViewHost*>(
- render_manager_.interstitial_render_view_host_);
- }
- TestRenderViewHost* original_rvh() {
- return static_cast<TestRenderViewHost*>(
- render_manager_.original_render_view_host_);
- }
-
- // State accessors.
- bool state_is_normal() const {
- return render_manager_.renderer_state_ == RenderViewHostManager::NORMAL;
- }
- bool state_is_pending() const {
- return render_manager_.renderer_state_ == RenderViewHostManager::PENDING;
- }
- bool state_is_entering_interstitial() const {
- return render_manager_.renderer_state_ ==
- RenderViewHostManager::ENTERING_INTERSTITIAL;
- }
- bool state_is_interstitial() const {
- return render_manager_.renderer_state_ ==
- RenderViewHostManager::INTERSTITIAL;
- }
- bool state_is_leaving_interstitial() const {
- return render_manager_.renderer_state_ ==
- RenderViewHostManager::LEAVING_INTERSTITIAL;
+
+ // State accessor.
+ bool cross_navigation_pending() {
+ return render_manager_.cross_navigation_pending_;
}
// Ensure we create TestRenderViewHosts that don't spawn processes.
@@ -250,28 +250,84 @@ class TestWebContents : public WebContents {
bool transition_cross_site;
};
-class WebContentsTest : public testing::Test {
+class TestInterstitialPage : public InterstitialPage {
public:
- WebContentsTest() : contents(NULL) {}
+ enum InterstitialState {
+ UNDECIDED = 0, // No decision taken yet.
+ OKED, // Proceed was called.
+ CANCELED // DontProceed was called.
+ };
+
+ TestInterstitialPage(WebContents* tab,
+ bool new_navigation,
+ const GURL& url,
+ InterstitialState* state,
+ bool* deleted)
+ : InterstitialPage(tab, new_navigation, url),
+ state_(state),
+ deleted_(deleted),
+ command_received_count_(0) {
+ *state_ = UNDECIDED;
+ *deleted_ = false;
+ }
+
+ virtual ~TestInterstitialPage() {
+ *deleted_ = true;
+ }
+
+ virtual void DontProceed() {
+ *state_ = CANCELED;
+ InterstitialPage::DontProceed();
+ }
+ virtual void Proceed() {
+ *state_ = OKED;
+ InterstitialPage::Proceed();
+ }
+
+ int command_received_count() const {
+ return command_received_count_;
+ }
- void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
- int pageID,
- const GURL& url) {
- params->page_id = pageID;
- params->url = url;
- params->referrer = GURL::EmptyGURL();
- params->transition = PageTransition::TYPED;
- params->redirects = std::vector<GURL>();
- params->should_update_history = false;
- params->searchable_form_url = GURL::EmptyGURL();
- params->searchable_form_element_name = std::wstring();
- params->searchable_form_encoding = std::string();
- params->password_form = PasswordForm();
- params->security_info = std::string();
- params->gesture = NavigationGestureUser;
- params->is_post = false;
+ void TestDomOperationResponse(const std::string& json_string) {
+ DomOperationResponse(json_string, 1);
}
+ void TestDidNavigate(int page_id, const GURL& url) {
+ ViewHostMsg_FrameNavigate_Params params;
+ InitNavigateParams(&params, page_id, url);
+ DidNavigate(render_view_host(), params);
+ }
+
+ void TestRendererGone() {
+ RendererGone(render_view_host());
+ }
+
+ bool is_showing() const {
+ return static_cast<TestRenderWidgetHostView*>(render_view_host()->view())->
+ is_showing();
+ }
+
+ protected:
+ virtual RenderViewHost* CreateRenderViewHost() {
+ return new TestRenderViewHost(
+ SiteInstance::CreateSiteInstance(tab()->profile()),
+ this, MSG_ROUTING_NONE, NULL);
+ }
+
+ virtual void CommandReceived(const std::string& command) {
+ command_received_count_++;
+ }
+
+ private:
+ InterstitialState* state_;
+ bool* deleted_;
+ int command_received_count_;
+};
+
+class WebContentsTest : public testing::Test {
+ public:
+ WebContentsTest() : contents(NULL) {}
+
// testing::Test methods:
virtual void SetUp() {
@@ -286,6 +342,7 @@ class WebContentsTest : public testing::Test {
virtual void TearDown() {
// This will delete the contents.
+ if (contents)
contents->CloseContents();
// Make sure that we flush any messages related to WebContents destruction
@@ -293,6 +350,13 @@ class WebContentsTest : public testing::Test {
MessageLoop::current()->RunAllPending();
}
+ void Navigate(int page_id, const GURL& url) {
+ DCHECK(contents);
+ ViewHostMsg_FrameNavigate_Params params;
+ InitNavigateParams(&params, page_id, url);
+ contents->TestDidNavigate(contents->rvh(), params);
+ }
+
scoped_ptr<WebContentsTestingProfile> profile;
TestWebContents* contents;
@@ -306,9 +370,9 @@ TEST_F(WebContentsTest, UpdateTitle) {
InitNavigateParams(&params, 0, GURL("about:blank"));
NavigationController::LoadCommittedDetails details;
- contents->controller()->RendererDidNavigate(params, false, &details);
+ contents->controller()->RendererDidNavigate(params, &details);
- contents->UpdateTitle(NULL, 0, L" Lots O' Whitespace\n");
+ contents->UpdateTitle(contents->rvh(), 0, L" Lots O' Whitespace\n");
EXPECT_EQ(std::wstring(L"Lots O' Whitespace"), contents->GetTitle());
}
@@ -317,14 +381,12 @@ TEST_F(WebContentsTest, SimpleNavigation) {
TestRenderViewHost* orig_rvh = contents->rvh();
SiteInstance* instance1 = contents->GetSiteInstance();
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
EXPECT_FALSE(orig_rvh->is_loading);
// Navigate to URL
const GURL url("http://www.google.com");
contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_TRUE(orig_rvh->is_loading);
EXPECT_EQ(instance1, orig_rvh->site_instance());
// Controller's pending entry will have a NULL site instance until we assign
@@ -336,7 +398,7 @@ TEST_F(WebContentsTest, SimpleNavigation) {
ViewHostMsg_FrameNavigate_Params params;
InitNavigateParams(&params, 1, url);
contents->TestDidNavigate(orig_rvh, params);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_EQ(instance1, orig_rvh->site_instance());
// Controller's entry should now have the SiteInstance, or else we won't be
@@ -345,260 +407,6 @@ TEST_F(WebContentsTest, SimpleNavigation) {
contents->controller()->GetActiveEntry()->site_instance());
}
-// Test navigating to a page that shows an interstitial, then hiding it
-// without proceeding.
-TEST_F(WebContentsTest, ShowInterstitialDontProceed) {
- TestRenderViewHost* orig_rvh = contents->rvh();
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
- EXPECT_FALSE(orig_rvh->is_loading);
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_TRUE(orig_rvh->is_loading);
-
- // Show interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- EXPECT_TRUE(contents->state_is_entering_interstitial());
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
- EXPECT_TRUE(orig_rvh->is_loading); // Still loading in the background
- EXPECT_TRUE(interstitial_rvh->is_loading);
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params;
- InitNavigateParams(&params, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_FALSE(interstitial_rvh->is_loading);
-
- // Hide interstitial (don't proceed)
- contents->HideInterstitialPage(false, false);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-}
-
-// Test navigating to a page that shows an interstitial, then proceeding.
-TEST_F(WebContentsTest, ShowInterstitialProceed) {
- TestRenderViewHost* orig_rvh = contents->rvh();
-
- // The RenderViewHost's SiteInstance should not yet have a site.
- EXPECT_EQ(GURL(), contents->rvh()->site_instance()->site());
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
-
- // Show interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params;
- InitNavigateParams(&params, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params);
-
- // Ensure this DidNavigate hasn't changed the SiteInstance's site.
- // Prevents regression for bug 1163298.
- EXPECT_EQ(GURL(), contents->rvh()->site_instance()->site());
-
- // Hide interstitial (proceed and wait)
- contents->HideInterstitialPage(true, true);
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
-
- // DidNavigate from the destination page
- contents->TestDidNavigate(orig_rvh, params);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // The SiteInstance's site should now be updated.
- EXPECT_EQ(GURL("http://google.com"),
- contents->rvh()->site_instance()->site());
-
- // Since we weren't viewing a page before, we shouldn't be able to go back.
- EXPECT_FALSE(contents->controller()->CanGoBack());
-}
-
-// Test navigating to a page that shows an interstitial, then navigating away.
-TEST_F(WebContentsTest, ShowInterstitialThenNavigate) {
- TestRenderViewHost* orig_rvh = contents->rvh();
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
-
- // Show interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params;
- InitNavigateParams(&params, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params);
-
- // While interstitial showing, navigate to a new URL.
- const GURL url2("http://www.yahoo.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_TRUE(orig_rvh->is_loading);
- EXPECT_FALSE(interstitial_rvh->is_loading);
-
- // DidNavigate from the new URL. In the old process model, we'll still have
- // the same RenderViewHost.
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 2, url2);
- contents->TestDidNavigate(orig_rvh, params2);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_FALSE(orig_rvh->is_loading);
-}
-
-// Ensures that an interstitial cannot be cancelled if a notification for a
-// navigation from an IFrame from the previous page is received while the
-// interstitial is being shown (bug #1182394).
-TEST_F(WebContentsTest, ShowInterstitialIFrameNavigate) {
- TestRenderViewHost* orig_rvh = contents->rvh();
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
- EXPECT_FALSE(orig_rvh->is_loading);
-
- // Navigate to URL.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_TRUE(orig_rvh->is_loading);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Show interstitial (in real world would probably be triggered by a resource
- // in the page).
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- EXPECT_TRUE(contents->state_is_entering_interstitial());
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
- EXPECT_TRUE(interstitial_rvh->is_loading);
-
- // DidNavigate from an IFrame in the initial page.
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, GURL("http://www.iframe.com"));
- params2.transition = PageTransition::AUTO_SUBFRAME;
- contents->TestDidNavigate(orig_rvh, params2);
-
- // Now we get the DidNavigate from the interstitial.
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params3);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_FALSE(interstitial_rvh->is_loading);
-}
-
-// Test navigating to an interstitial page from a normal page. Also test
-// visiting the interstitial-inducing URL twice (bug 1079784), and test
-// that going back shows the first page and not the interstitial.
-TEST_F(WebContentsTest, VisitInterstitialURLTwice) {
- TestRenderViewHost* orig_rvh = contents->rvh();
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Now navigate to an interstitial-inducing URL
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- EXPECT_TRUE(contents->state_is_entering_interstitial());
- int interstitial_delete_counter = 0;
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
- interstitial_rvh->set_delete_counter(&interstitial_delete_counter);
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 2, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
-
- // While interstitial showing, navigate to the same URL.
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
-
- // Interstitial shown a second time in a different RenderViewHost.
- interstitial = new InterstitialPage(contents, true, interstitial_url);
- interstitial->Show();
- EXPECT_TRUE(contents->state_is_entering_interstitial());
- // We expect the original interstitial has been deleted.
- EXPECT_EQ(interstitial_delete_counter, 1);
- TestRenderViewHost* interstitial_rvh2 = contents->interstitial_rvh();
- interstitial_rvh2->set_delete_counter(&interstitial_delete_counter);
-
- // DidNavigate from the interstitial.
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 3, url2);
- contents->TestDidNavigate(interstitial_rvh2, params3);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh2, contents->render_view_host());
-
- // Proceed. In the old process model, we'll still have the same
- // RenderViewHost.
- contents->HideInterstitialPage(true, true);
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- ViewHostMsg_FrameNavigate_Params params4;
- InitNavigateParams(&params4, 3, url2);
- contents->TestDidNavigate(orig_rvh, params4);
- EXPECT_TRUE(contents->state_is_normal());
- // We expect the second interstitial has been deleted.
- EXPECT_EQ(interstitial_delete_counter, 2);
-
- // Now go back. Should take us back to the original page.
- contents->controller()->GoBack();
- EXPECT_TRUE(contents->state_is_normal());
-
- // DidNavigate from going back.
- contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-}
-
// Test that navigating across a site boundary creates a new RenderViewHost
// with a new SiteInstance. Going back should do the same.
TEST_F(WebContentsTest, CrossSiteBoundaries) {
@@ -615,15 +423,13 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
// Navigate to new site
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_pending());
+ EXPECT_TRUE(contents->cross_navigation_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
int pending_rvh_delete_count = 0;
pending_rvh->set_delete_counter(&pending_rvh_delete_count);
@@ -634,23 +440,21 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
contents->TestDidNavigate(pending_rvh, params2);
SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
EXPECT_EQ(orig_rvh_delete_count, 1);
// Going back should switch SiteInstances again. The first SiteInstance is
// stored in the NavigationEntry, so it should be the same as at the start.
contents->controller()->GoBack();
TestRenderViewHost* goback_rvh = contents->pending_rvh();
- EXPECT_TRUE(contents->state_is_pending());
+ EXPECT_TRUE(contents->cross_navigation_pending());
// DidNavigate from the back action
contents->TestDidNavigate(goback_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(goback_rvh, contents->render_view_host());
EXPECT_EQ(pending_rvh_delete_count, 1);
EXPECT_EQ(instance1, contents->GetSiteInstance());
@@ -672,10 +476,8 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
// Crash the renderer.
orig_rvh->is_created = false;
@@ -684,10 +486,8 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
TestRenderViewHost* new_rvh = contents->rvh();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
EXPECT_NE(orig_rvh, new_rvh);
EXPECT_EQ(orig_rvh_delete_count, 1);
@@ -697,330 +497,10 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
contents->TestDidNavigate(new_rvh, params2);
SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(new_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-}
-
-// Test state transitions when showing an interstitial in the new process
-// model, and then choosing DontProceed.
-TEST_F(WebContentsTest, CrossSiteInterstitialDontProceed) {
- contents->transition_cross_site = true;
- TestRenderViewHost* orig_rvh = contents->rvh();
- SiteInstance* instance1 = contents->GetSiteInstance();
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_pending());
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- EXPECT_TRUE(contents->state_is_entering_interstitial());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_EQ(pending_rvh, contents->pending_rvh());
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 2, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_EQ(pending_rvh, contents->pending_rvh());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Hide interstitial (don't proceed)
- contents->HideInterstitialPage(false, false);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-}
-
-// Test state transitions when showing an interstitial in the new process
-// model, and then choosing Proceed.
-TEST_F(WebContentsTest, CrossSiteInterstitialProceed) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
- SiteInstance* instance1 = contents->GetSiteInstance();
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
- int pending_rvh_delete_count = 0;
- pending_rvh->set_delete_counter(&pending_rvh_delete_count);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_EQ(pending_rvh, contents->pending_rvh());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Hide interstitial (proceed and wait)
- contents->HideInterstitialPage(true, true);
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_EQ(pending_rvh, contents->pending_rvh());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // DidNavigate from the destination page should transition to new renderer
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 2, url2);
- contents->TestDidNavigate(pending_rvh, params3);
- SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(pending_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
- EXPECT_NE(instance1, instance2);
- EXPECT_EQ(orig_rvh_delete_count, 1); // The original should be gone.
-
- // Since we were viewing a page before, we should be able to go back.
- EXPECT_TRUE(contents->controller()->CanGoBack());
-
- // Going back should switch SiteInstances again. The first SiteInstance is
- // stored in the NavigationEntry, so it should be the same as at the start.
- contents->controller()->GoBack();
- TestRenderViewHost* goback_rvh = contents->pending_rvh();
- EXPECT_TRUE(contents->state_is_pending());
-
- // DidNavigate from the back action
- contents->TestDidNavigate(goback_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(goback_rvh, contents->render_view_host());
- EXPECT_EQ(instance1, contents->GetSiteInstance());
- EXPECT_EQ(pending_rvh_delete_count, 1); // The second page's rvh should die.
-}
-
-// Tests that we can transition away from an interstitial page.
-TEST_F(WebContentsTest, CrossSiteInterstitialThenNavigate) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- false,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Navigate to a new page.
- const GURL url2("http://www.yahoo.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
-
- TestRenderViewHost* new_rvh = contents->pending_rvh();
- ASSERT_TRUE(new_rvh != NULL);
- // Make sure the RVH is not suspended (bug #1236441).
- EXPECT_FALSE(new_rvh->IsNavigationSuspended());
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
-
- // DidNavigate from the new page
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url2);
- contents->TestDidNavigate(new_rvh, params3);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(new_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_EQ(orig_rvh_delete_count, 1);
-}
-
-// Tests that we can transition away from an interstitial page even if the
-// interstitial renderer has crashed.
-TEST_F(WebContentsTest, CrossSiteInterstitialCrashThenNavigate) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
- int pending_rvh_delete_count = 0;
- pending_rvh->set_delete_counter(&pending_rvh_delete_count);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_EQ(pending_rvh, contents->pending_rvh());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Crash the interstitial RVH
- // (by making IsRenderViewLive() == false)
- interstitial_rvh->is_created = false;
-
- // Navigate to a new page. Since interstitial RVH is dead, we should clean
- // it up and go to a new PENDING state, showing the orig_rvh.
- const GURL url3("http://www.yahoo.com");
- contents->controller()->LoadURL(url3, GURL(), PageTransition::TYPED);
- TestRenderViewHost* new_rvh = contents->pending_rvh();
- ASSERT_TRUE(new_rvh != NULL);
- EXPECT_TRUE(contents->state_is_pending());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_EQ(pending_rvh_delete_count, 1);
- EXPECT_NE(interstitial_rvh, new_rvh);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // DidNavigate from the new page
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url3);
- contents->TestDidNavigate(new_rvh, params3);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(new_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_EQ(orig_rvh_delete_count, 1);
-}
-
-// Tests that we can transition away from an interstitial page even if both the
-// original and interstitial renderers have crashed.
-TEST_F(WebContentsTest, CrossSiteInterstitialCrashesThenNavigate) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
- int pending_rvh_delete_count = 0;
- pending_rvh->set_delete_counter(&pending_rvh_delete_count);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_TRUE(contents->state_is_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
- EXPECT_EQ(orig_rvh, contents->original_rvh());
- EXPECT_EQ(pending_rvh, contents->pending_rvh());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Crash both the original and interstitial RVHs
- // (by making IsRenderViewLive() == false)
- orig_rvh->is_created = false;
- interstitial_rvh->is_created = false;
-
- // Navigate to a new page. Since both the interstitial and original RVHs are
- // dead, we should create a new RVH, jump back to NORMAL, and navigate.
- const GURL url3("http://www.yahoo.com");
- contents->controller()->LoadURL(url3, GURL(), PageTransition::TYPED);
- TestRenderViewHost* new_rvh = contents->rvh();
- ASSERT_TRUE(new_rvh != NULL);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh_delete_count, 1);
- EXPECT_EQ(pending_rvh_delete_count, 1);
- EXPECT_NE(interstitial_rvh, new_rvh);
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // DidNavigate from the new page
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url3);
- contents->TestDidNavigate(new_rvh, params3);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(new_rvh, contents->render_view_host());
}
// Test that opening a new tab in the same SiteInstance and then navigating
@@ -1062,7 +542,7 @@ TEST_F(WebContentsTest, NavigateTwoTabsCrossSite) {
contents2->controller()->LoadURL(url2b, GURL(), PageTransition::TYPED);
TestRenderViewHost* pending_rvh_b = contents2->pending_rvh();
EXPECT_TRUE(pending_rvh_b != NULL);
- EXPECT_TRUE(contents2->state_is_pending());
+ EXPECT_TRUE(contents2->cross_navigation_pending());
// NOTE(creis): We used to be in danger of showing a sad tab page here if the
// second tab hadn't navigated somewhere first (bug 1145430). That case is
@@ -1100,16 +580,16 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
contents2->SetupController(profile.get());
const GURL url2("http://www.yahoo.com");
contents2->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- // The first RVH in contents2 isn't live yet, so we shortcut the PENDING
- // state and go straight to NORMAL.
+ // The first RVH in contents2 isn't live yet, so we shortcut the cross site
+ // pending.
TestRenderViewHost* rvh2 = contents2->rvh();
- EXPECT_TRUE(contents2->state_is_normal());
+ EXPECT_FALSE(contents2->cross_navigation_pending());
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents2->TestDidNavigate(rvh2, params2);
SiteInstance* instance2 = contents2->GetSiteInstance();
EXPECT_NE(instance1, instance2);
- EXPECT_TRUE(contents2->state_is_normal());
+ EXPECT_FALSE(contents2->cross_navigation_pending());
// Simulate a link click in first tab to second site. Doesn't switch
// SiteInstances, because we don't intercept WebKit navigations.
@@ -1118,13 +598,13 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
contents->TestDidNavigate(orig_rvh, params3);
SiteInstance* instance3 = contents->GetSiteInstance();
EXPECT_EQ(instance1, instance3);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
// Navigate to the new site. Doesn't switch SiteInstancees, because we
// compare against the current URL, not the SiteInstance's site.
const GURL url3("http://mail.yahoo.com");
contents->controller()->LoadURL(url3, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
ViewHostMsg_FrameNavigate_Params params4;
InitNavigateParams(&params4, 3, url3);
contents->TestDidNavigate(orig_rvh, params4);
@@ -1147,7 +627,7 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate to new site, but simulate an onbeforeunload denial.
@@ -1155,13 +635,13 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
orig_rvh->immediate_before_unload = false;
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
orig_rvh->TestOnMsgShouldClose(false);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate again, but simulate an onbeforeunload approval.
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
orig_rvh->TestOnMsgShouldClose(true);
- EXPECT_TRUE(contents->state_is_pending());
+ EXPECT_TRUE(contents->cross_navigation_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
// We won't hear DidNavigate until the onunload handler has finished running.
@@ -1173,12 +653,10 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
InitNavigateParams(&params2, 1, url2);
contents->TestDidNavigate(pending_rvh, params2);
SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
}
// Test that NavigationEntries have the correct content state after going
@@ -1253,3 +731,472 @@ TEST_F(WebContentsTest, WebKitPrefs) {
EXPECT_EQ(true, webkit_prefs.javascript_enabled);
}
+////////////////////////////////////////////////////////////////////////////////
+// Interstitial Tests
+////////////////////////////////////////////////////////////////////////////////
+
+// Test navigating to a page (with the navigation initiated from the browser,
+// as when a URL is typed in the location bar) that shows an interstitial and
+// creates a new navigation entry, then hiding it without proceeding.
+TEST_F(WebContentsTest,
+ ShowInterstitialFromBrowserWithNewNavigationDontProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Initiate a browser navigation that will trigger the interstitial
+ contents->controller()->LoadURL(GURL("http://www.evil.com"), GURL(),
+ PageTransition::TYPED);
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Now don't proceed.
+ interstitial->DontProceed();
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page (with the navigation initiated from the renderer,
+// as when clicking on a link in the page) that shows an interstitial and
+// creates a new navigation entry, then hiding it without proceeding.
+TEST_F(WebContentsTest,
+ ShowInterstitiaFromRendererlWithNewNavigationDontProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial (no pending entry, the interstitial would have been
+ // triggered by clicking on a link).
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Now don't proceed.
+ interstitial->DontProceed();
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page that shows an interstitial without creating a new
+// navigation entry (this happens when the interstitial is triggered by a
+// sub-resource in the page), then hiding it without proceeding.
+TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationDontProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, false, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ // The URL specified to the interstitial should have been ignored.
+ EXPECT_TRUE(entry->url() == url1);
+
+ // Now don't proceed.
+ interstitial->DontProceed();
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page (with the navigation initiated from the browser,
+// as when a URL is typed in the location bar) that shows an interstitial and
+// creates a new navigation entry, then proceeding.
+TEST_F(WebContentsTest, ShowInterstitialFromBrowserNewNavigationProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Initiate a browser navigation that will trigger the interstitial
+ contents->controller()->LoadURL(GURL("http://www.evil.com"), GURL(),
+ PageTransition::TYPED);
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Then proceed.
+ interstitial->Proceed();
+ // The interstitial should show until the new navigation commits.
+ ASSERT_FALSE(deleted);
+ EXPECT_EQ(TestInterstitialPage::OKED, state);
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+
+ // Simulate the navigation to the page, that's when the interstitial gets
+ // hidden.
+ GURL url3("http://www.thepage.com");
+ Navigate(2, url3);
+
+ EXPECT_TRUE(deleted);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url3);
+
+ EXPECT_EQ(2, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page (with the navigation initiated from the renderer,
+// as when clicking on a link in the page) that shows an interstitial and
+// creates a new navigation entry, then proceeding.
+TEST_F(WebContentsTest, ShowInterstitialFromRendererNewNavigationProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Then proceed.
+ interstitial->Proceed();
+ // The interstitial should show until the new navigation commits.
+ ASSERT_FALSE(deleted);
+ EXPECT_EQ(TestInterstitialPage::OKED, state);
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+
+ // Simulate the navigation to the page, that's when the interstitial gets
+ // hidden.
+ GURL url3("http://www.thepage.com");
+ Navigate(2, url3);
+
+ EXPECT_TRUE(deleted);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url3);
+
+ EXPECT_EQ(2, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page that shows an interstitial without creating a new
+// navigation entry (this happens when the interstitial is triggered by a
+// sub-resource in the page), then proceeding.
+TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationProceed) {
+ // Navigate to a page so we have a navigation entry in the controller.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, false, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ // The URL specified to the interstitial should have been ignored.
+ EXPECT_TRUE(entry->url() == url1);
+
+ // Then proceed.
+ interstitial->Proceed();
+ // Since this is not a new navigation, the previous page is dismissed right
+ // away and shows the original page.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::OKED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page that shows an interstitial, then navigating away.
+TEST_F(WebContentsTest, ShowInterstitialThenNavigate) {
+ // Show interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url);
+
+ // While interstitial showing, navigate to a new URL.
+ const GURL url2("http://www.yahoo.com");
+ Navigate(1, url2);
+
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
+
+// Test navigating to a page that shows an interstitial, then close the tab.
+TEST_F(WebContentsTest, ShowInterstitialThenCloseTab) {
+ // Show interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url);
+
+ // Now close the tab.
+ contents->CloseContents();
+ contents = NULL; // So we don't detroy it again on TearDown.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
+
+// Test that after Proceed is called and an interstitial is still shown, no more
+// commands get executed.
+TEST_F(WebContentsTest, ShowInterstitialProceedMultipleCommands) {
+ // Navigate to a page so we have a navigation entry in the controller.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url2);
+
+ // Run a command.
+ EXPECT_EQ(0, interstitial->command_received_count());
+ interstitial->TestDomOperationResponse("toto");
+ EXPECT_EQ(1, interstitial->command_received_count());
+
+ // Then proceed.
+ interstitial->Proceed();
+ ASSERT_FALSE(deleted);
+
+ // While the navigation to the new page is pending, send other commands, they
+ // should be ignored.
+ interstitial->TestDomOperationResponse("hello");
+ interstitial->TestDomOperationResponse("hi");
+ EXPECT_EQ(1, interstitial->command_received_count());
+}
+
+// Test showing an interstitial while another interstitial is already showing.
+TEST_F(WebContentsTest, ShowInterstitialOnInterstitial) {
+ // Navigate to a page so we have a navigation entry in the controller.
+ GURL start_url("http://www.google.com");
+ Navigate(1, start_url);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state1 =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted1 = false;
+ GURL url1("http://interstitial1");
+ TestInterstitialPage* interstitial1 =
+ new TestInterstitialPage(contents, true, url1, &state1, &deleted1);
+ interstitial1->Show();
+ interstitial1->TestDidNavigate(1, url1);
+
+ // Now show another interstitial.
+ TestInterstitialPage::InterstitialState state2 =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted2 = false;
+ GURL url2("http://interstitial2");
+ TestInterstitialPage* interstitial2 =
+ new TestInterstitialPage(contents, true, url2, &state2, &deleted2);
+ interstitial2->Show();
+ interstitial2->TestDidNavigate(1, url2);
+
+ // Showing interstitial2 should have caused interstitial1 to go away.
+ EXPECT_TRUE(deleted1);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
+
+ // Let's make sure interstitial2 is working as intended.
+ ASSERT_FALSE(deleted2);
+ EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
+ interstitial2->Proceed();
+ GURL landing_url("http://www.thepage.com");
+ Navigate(2, landing_url);
+
+ EXPECT_TRUE(deleted2);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == landing_url);
+ EXPECT_EQ(2, contents->controller()->GetEntryCount());
+}
+
+// Test that navigating away from an interstitial while it's loading cause it
+// not to show.
+TEST_F(WebContentsTest, NavigateBeforeInterstitialShows) {
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL interstitial_url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, interstitial_url,
+ &state, &deleted);
+ interstitial->Show();
+
+ // Let's simulate a navigation initiated from the browser before the
+ // interstitial finishes loading.
+ const GURL url("http://www.google.com");
+ contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ ASSERT_FALSE(deleted);
+ EXPECT_FALSE(interstitial->is_showing());
+
+ // Now let's make the interstitial navigation commit.
+ interstitial->TestDidNavigate(1, interstitial_url);
+
+ // After it loaded the interstitial should be gone.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
+
+// Test showing an interstitial and have its renderer crash.
+TEST_F(WebContentsTest, InterstitialCrasher) {
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ // Simulate a renderer crash before the interstitial is shown.
+ interstitial->TestRendererGone();
+ // The interstitial should have been dismissed.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+
+ // Now try again but this time crash the intersitial after it was shown.
+ interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url);
+ // Simulate a renderer crash.
+ interstitial->TestRendererGone();
+ // The interstitial should have been dismissed.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}