15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/test_render_view_host.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/site_instance_impl.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/web_contents/frame_tree_node.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/interstitial_page_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/navigation_entry_impl.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/web_ui_controller_factory_registry.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/global_request_id.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/interstitial_page_delegate.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_controller.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_render_process_host.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/test_content_browser_client.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/test_content_client.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/test_web_contents.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestWebUIUrl[] = "chrome://blah";
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebContentsImplTestWebUIControllerFactory
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public WebUIControllerFactory {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebUIController* CreateWebUIControllerForURL(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebUI* web_ui, const GURL& url) const OVERRIDE {
442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (!UseWebUI(url))
452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return NULL;
462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return new WebUIController(web_ui);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url) const OVERRIDE {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WebUI::kNoWebUI;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool UseWebUIForURL(BrowserContext* browser_context,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const GURL& url) const OVERRIDE {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UseWebUI(url);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const GURL& url) const OVERRIDE {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UseWebUI(url);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UseWebUI(const GURL& url) const {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return url == GURL(kTestWebUIUrl);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestInterstitialPage;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestInterstitialPageDelegate : public InterstitialPageDelegate {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  explicit TestInterstitialPageDelegate(TestInterstitialPage* interstitial_page)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : interstitial_page_(interstitial_page) {}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CommandReceived(const std::string& command) OVERRIDE;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetHTMLContents() OVERRIDE { return std::string(); }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnDontProceed() OVERRIDE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnProceed() OVERRIDE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial_page_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestInterstitialPage : public InterstitialPageImpl {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum InterstitialState {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    INVALID = 0,    // Hasn't yet been initialized.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UNDECIDED,      // Initialized, but no decision taken yet.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OKED,           // Proceed was called.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CANCELED        // DontProceed was called.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Delegate {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void TestInterstitialPageDeleted(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestInterstitialPage* interstitial) = 0;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate() {}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IMPORTANT NOTE: if you pass stack allocated values for |state| and
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |deleted| (like all interstitial related tests do at this point), make sure
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to create an instance of the TestInterstitialPageStateGuard class on the
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stack in your test.  This will ensure that the TestInterstitialPage states
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are cleared when the test finishes.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not doing so will cause stack trashing if your test does not hide the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interstitial, as in such a case it will be destroyed in the test TearDown
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method and will dereference the |deleted| local variable which by then is
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // out of scope.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage(WebContentsImpl* contents,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool new_navigation,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const GURL& url,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InterstitialState* state,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool* deleted)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : InterstitialPageImpl(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            contents, new_navigation, url,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new TestInterstitialPageDelegate(this)),
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state),
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        deleted_(deleted),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_received_count_(0),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_(NULL) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *state_ = UNDECIDED;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *deleted_ = false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestInterstitialPage() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (deleted_)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *deleted_ = true;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->TestInterstitialPageDeleted(this);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDontProceed() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state_)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *state_ = CANCELED;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnProceed() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state_)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *state_ = OKED;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int command_received_count() const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return command_received_count_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestDomOperationResponse(const std::string& json_string) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enabled())
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommandReceived();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestDidNavigate(int page_id, const GURL& url) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewHostMsg_FrameNavigate_Params params;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitNavigateParams(&params, page_id, url, PAGE_TRANSITION_TYPED);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DidNavigate(GetRenderViewHostForTesting(), params);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void TestRenderViewTerminated(base::TerminationStatus status,
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                int error_code) {
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderViewTerminated(GetRenderViewHostForTesting(), status, error_code);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_showing() const {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<TestRenderWidgetHostView*>(
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetRenderViewHostForTesting()->GetView())->is_showing();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearStates() {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_ = NULL;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    deleted_ = NULL;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = NULL;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CommandReceived() {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_received_count_++;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_delegate(Delegate* delegate) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = delegate;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual RenderViewHost* CreateRenderViewHost() OVERRIDE {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new TestRenderViewHost(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SiteInstance::Create(web_contents()->GetBrowserContext()),
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        this, this, MSG_ROUTING_NONE, MSG_ROUTING_NONE, false);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebContentsView* CreateWebContentsView() OVERRIDE {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InterstitialState* state_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool* deleted_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int command_received_count_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Delegate* delegate_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestInterstitialPageDelegate::CommandReceived(const std::string& command) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial_page_->CommandReceived();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestInterstitialPageDelegate::OnDontProceed() {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial_page_->OnDontProceed();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestInterstitialPageDelegate::OnProceed() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial_page_->OnProceed();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestInterstitialPageStateGuard : public TestInterstitialPage::Delegate {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestInterstitialPageStateGuard(
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestInterstitialPage* interstitial_page)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : interstitial_page_(interstitial_page) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(interstitial_page_);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interstitial_page_->set_delegate(this);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestInterstitialPageStateGuard() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (interstitial_page_)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interstitial_page_->ClearStates();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TestInterstitialPageDeleted(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage* interstitial) OVERRIDE {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(interstitial_page_ == interstitial);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interstitial_page_ = NULL;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial_page_;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass WebContentsImplTestBrowserClient : public TestContentBrowserClient {
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebContentsImplTestBrowserClient()
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : assign_site_for_url_(false) {}
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual ~WebContentsImplTestBrowserClient() {}
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool ShouldAssignSiteForURL(const GURL& url) OVERRIDE {
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return assign_site_for_url_;
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void set_assign_site_for_url(bool assign) {
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    assign_site_for_url_ = assign;
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool assign_site_for_url_;
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebContentsImplTest : public RenderViewHostImplTestHarness {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostImplTestHarness::SetUp();
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebUIControllerFactory::RegisterFactory(&factory_);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RenderViewHostImplTestHarness::TearDown();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContentsImplTestWebUIControllerFactory factory_;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestWebContentsObserver : public WebContentsObserver {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  explicit TestWebContentsObserver(WebContents* contents)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : WebContentsObserver(contents) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestWebContentsObserver() {}
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidFinishLoad(int64 frame_id,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const GURL& validated_url,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             bool is_main_frame,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             RenderViewHost* render_view_host) OVERRIDE {
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_url_ = validated_url;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidFailLoad(int64 frame_id,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const GURL& validated_url,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool is_main_frame,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           int error_code,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const string16& error_description,
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           RenderViewHost* render_view_host) OVERRIDE {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_url_ = validated_url;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL& last_url() const { return last_url_; }
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL last_url_;
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver);
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test to make sure that title updates get stripped of whitespace.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, UpdateTitle) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& cont =
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<NavigationControllerImpl&>(controller());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewHostMsg_FrameNavigate_Params params;
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  InitNavigateParams(&params, 0, GURL(kAboutBlankURL), PAGE_TRANSITION_TYPED);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cont.RendererDidNavigate(params, &details);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->UpdateTitle(rvh(), 0, ASCIIToUTF16("    Lots O' Whitespace\n"),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::i18n::LEFT_TO_RIGHT);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("Lots O' Whitespace"), contents()->GetTitle());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test view source mode for a webui page.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NTPViewSource) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& cont =
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<NavigationControllerImpl&>(controller());
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kUrl[] = "view-source:chrome://blah";
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kGURL(kUrl);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process()->sink().ClearMessages();
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cont.LoadURL(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rvh()->GetDelegate()->RenderViewCreated(rvh());
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Did we get the expected message?
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process()->sink().GetFirstMessageMatching(
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ViewMsg_EnableViewSourceMode::ID));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewHostMsg_FrameNavigate_Params params;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitNavigateParams(&params, 0, kGURL, PAGE_TRANSITION_TYPED);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cont.RendererDidNavigate(params, &details);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also check title and url.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kUrl), contents()->GetTitle());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test to ensure UpdateMaxPageID is working properly.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, UpdateMaxPageID) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SiteInstance> instance2(SiteInstance::Create(NULL));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts at -1.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, contents()->GetMaxPageID());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, contents()->GetMaxPageIDForSiteInstance(instance1));
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(-1, contents()->GetMaxPageIDForSiteInstance(instance2.get()));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure max_page_id_ is monotonically increasing per SiteInstance.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->UpdateMaxPageID(3);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->UpdateMaxPageID(1);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, contents()->GetMaxPageID());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, contents()->GetMaxPageIDForSiteInstance(instance1));
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(-1, contents()->GetMaxPageIDForSiteInstance(instance2.get()));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  contents()->UpdateMaxPageIDForSiteInstance(instance2.get(), 7);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, contents()->GetMaxPageID());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, contents()->GetMaxPageIDForSiteInstance(instance1));
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(7, contents()->GetMaxPageIDForSiteInstance(instance2.get()));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test simple same-SiteInstance navigation.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, SimpleNavigation) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, orig_rvh->GetSiteInstance());
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Controller's pending entry will have a NULL site instance until we assign
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it in DidNavigate.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller().GetActiveEntry())->
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          site_instance() == NULL);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the page
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, orig_rvh->GetSiteInstance());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Controller's entry should now have the SiteInstance, or else we won't be
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // able to find it later.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance1,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller().GetActiveEntry())->
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          site_instance());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we reject NavigateToEntry if the url is over kMaxURLChars.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NavigateToExcessivelyLongURL) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct a URL that's kMaxURLChars + 1 long of all 'a's.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url(std::string("http://example.org/").append(
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMaxURLChars + 1, 'a'));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_GENERATED, std::string());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller().GetActiveEntry() == NULL);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that navigating across a site boundary creates a new RenderViewHost
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with a new SiteInstance.  Going back should do the same.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int orig_rvh_delete_count = 0;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->set_delete_counter(&orig_rvh_delete_count);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep the number of active views in orig_rvh's SiteInstance
4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // non-zero so that orig_rvh doesn't get deleted when it gets
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // swapped out.
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<SiteInstanceImpl*>(orig_rvh->GetSiteInstance())->
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(url, contents()->GetLastCommittedURL());
430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(url, contents()->GetVisibleURL());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(url, contents()->GetLastCommittedURL());
438ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(url2, contents()->GetVisibleURL());
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* pending_rvh =
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pending_rvh_delete_count = 0;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_rvh->set_delete_counter(&pending_rvh_delete_count);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigations should be suspended in pending_rvh until ShouldCloseACK.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pending_rvh->are_navigations_suspended());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->SendShouldCloseACK(true);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(pending_rvh->are_navigations_suspended());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the pending page
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep the number of active views in pending_rvh's SiteInstance
4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // non-zero so that orig_rvh doesn't get deleted when it gets
4567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // swapped out.
4577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<SiteInstanceImpl*>(pending_rvh->GetSiteInstance())->
4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
4597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost());
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(url2, contents()->GetLastCommittedURL());
463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(url2, contents()->GetVisibleURL());
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We keep the original RVH around, swapped out.
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->IsOnSwappedOutList(
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      orig_rvh));
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh_delete_count, 0);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Going back should switch SiteInstances again.  The first SiteInstance is
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stored in the NavigationEntry, so it should be the same as at the start.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should use the same RVH as before, swapping it back in.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().GoBack();
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* goback_rvh =
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, goback_rvh);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigations should be suspended in goback_rvh until ShouldCloseACK.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(goback_rvh->are_navigations_suspended());
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_rvh->SendShouldCloseACK(true);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(goback_rvh->are_navigations_suspended());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the back action
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      goback_rvh, 1, url2, PAGE_TRANSITION_TYPED);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(goback_rvh, contents()->GetRenderViewHost());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, contents()->GetSiteInstance());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pending RVH should now be swapped out, not deleted.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IsOnSwappedOutList(pending_rvh));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(pending_rvh_delete_count, 0);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close contents and ensure RVHs are deleted.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteContents();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh_delete_count, 1);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(pending_rvh_delete_count, 1);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that navigating across a site boundary after a crash creates a new
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RVH without requiring a cross-site transition (i.e., PENDING state).
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteBoundariesAfterCrash) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int orig_rvh_delete_count = 0;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->set_delete_counter(&orig_rvh_delete_count);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Crash the renderer.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->set_render_view_created(false);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site.  We should not go into PENDING.
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* new_rvh = rvh();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(orig_rvh, new_rvh);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh_delete_count, 1);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the new page
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(new_rvh, 1, url2, PAGE_TRANSITION_TYPED);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(new_rvh, rvh());
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close contents and ensure RVHs are deleted.
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteContents();
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh_delete_count, 1);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that opening a new contents in the same SiteInstance and then navigating
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// both contentses to a new site will place both contentses in a single
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SiteInstance.
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NavigateTwoTabsCrossSite) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a new contents with the same SiteInstance, navigated to the same site.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> contents2(
5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      TestWebContents::Create(browser_context(), instance1));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->transition_cross_site = true;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->GetController().LoadURL(url, Referrer(),
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PAGE_TRANSITION_TYPED,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string());
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need this page id to be 2 since the site instance is the same (which is the
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scope of page IDs) and we want to consider this a new page.
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->TestDidNavigate(
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents2->GetRenderViewHost(), 2, url, PAGE_TRANSITION_TYPED);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate first contents to a new site.
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2a("http://www.yahoo.com");
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2a, Referrer(), PAGE_TRANSITION_TYPED, std::string());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->SendShouldCloseACK(true);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* pending_rvh_a =
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_rvh_a, 1, url2a, PAGE_TRANSITION_TYPED);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2a = contents()->GetSiteInstance();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2a);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate second contents to the same site as the first tab.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2b("http://mail.yahoo.com");
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->GetController().LoadURL(url2b, Referrer(),
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PAGE_TRANSITION_TYPED,
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh2 =
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents2->GetRenderViewHost());
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rvh2->SendShouldCloseACK(true);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* pending_rvh_b =
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents2->GetPendingRenderViewHost());
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pending_rvh_b != NULL);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents2->cross_navigation_pending());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE(creis): We used to be in danger of showing a crash page here if the
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second contents hadn't navigated somewhere first (bug 1145430).  That case
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is now covered by the CrossSiteBoundariesAfterCrash test.
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->TestDidNavigate(
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_rvh_b, 2, url2b, PAGE_TRANSITION_TYPED);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2b = contents2->GetSiteInstance();
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2b);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both contentses should now be in the same SiteInstance.
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance2a, instance2b);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(WebContentsImplTest, NavigateDoesNotUseUpSiteInstance) {
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebContentsImplTestBrowserClient browser_client;
6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SetBrowserClientForTesting(&browser_client);
6137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  contents()->transition_cross_site = true;
615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestRenderViewHost* orig_rvh = test_rvh();
616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int orig_rvh_delete_count = 0;
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  orig_rvh->set_delete_counter(&orig_rvh_delete_count);
618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SiteInstanceImpl* orig_instance =
619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      static_cast<SiteInstanceImpl*>(contents()->GetSiteInstance());
620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  browser_client.set_assign_site_for_url(false);
6227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Navigate to an URL that will not assign a new SiteInstance.
6237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const GURL native_url("non-site-url://stuffandthings");
624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  controller().LoadURL(
625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      native_url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  contents()->TestDidNavigate(orig_rvh, 1, native_url, PAGE_TRANSITION_TYPED);
627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(native_url, contents()->GetLastCommittedURL());
631ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(native_url, contents()->GetVisibleURL());
632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(orig_instance, contents()->GetSiteInstance());
633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(GURL(), contents()->GetSiteInstance()->GetSiteURL());
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(orig_instance->HasSite());
635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  browser_client.set_assign_site_for_url(true);
637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Navigate to new site (should keep same site instance).
638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const GURL url("http://www.google.com");
639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  controller().LoadURL(
640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(native_url, contents()->GetLastCommittedURL());
643ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(url, contents()->GetVisibleURL());
644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(contents()->GetPendingRenderViewHost());
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
6467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep the number of active views in orig_rvh's SiteInstance
6487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // non-zero so that orig_rvh doesn't get deleted when it gets
6497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // swapped out.
6507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<SiteInstanceImpl*>(orig_rvh->GetSiteInstance())->
6517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
6527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(orig_instance, contents()->GetSiteInstance());
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(
655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      contents()->GetSiteInstance()->GetSiteURL().DomainIs("google.com"));
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(url, contents()->GetLastCommittedURL());
657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Navigate to another new site (should create a new site instance).
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const GURL url2("http://www.yahoo.com");
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  controller().LoadURL(
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(url, contents()->GetLastCommittedURL());
664ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(url2, contents()->GetVisibleURL());
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestRenderViewHost* pending_rvh =
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int pending_rvh_delete_count = 0;
668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  pending_rvh->set_delete_counter(&pending_rvh_delete_count);
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Navigations should be suspended in pending_rvh until ShouldCloseACK.
671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(pending_rvh->are_navigations_suspended());
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  orig_rvh->SendShouldCloseACK(true);
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(pending_rvh->are_navigations_suspended());
674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // DidNavigate from the pending page.
676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  contents()->TestDidNavigate(
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SiteInstance* new_instance = contents()->GetSiteInstance();
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost());
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(url2, contents()->GetLastCommittedURL());
683ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(url2, contents()->GetVisibleURL());
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_NE(new_instance, orig_instance);
685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(contents()->GetPendingRenderViewHost());
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We keep the original RVH around, swapped out.
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(contents()->GetRenderManagerForTesting()->IsOnSwappedOutList(
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      orig_rvh));
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(orig_rvh_delete_count, 0);
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Close contents and ensure RVHs are deleted.
692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DeleteContents();
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(orig_rvh_delete_count, 1);
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(pending_rvh_delete_count, 1);
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that we can find an opener RVH even if it's pending.
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://crbug.com/176252.
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WebContentsImplTest, FindOpenerRVHWhenPending) {
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->transition_cross_site = true;
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to a URL.
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url("http://www.google.com");
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller().LoadURL(
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start to navigate first tab to a new site, so that it has a pending RVH.
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://www.yahoo.com");
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller().LoadURL(
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  orig_rvh->SendShouldCloseACK(true);
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestRenderViewHost* pending_rvh =
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // While it is still pending, simulate opening a new tab with the first tab
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as its opener.  This will call WebContentsImpl::CreateOpenerRenderViews
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on the opener to ensure that an RVH exists.
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int opener_routing_id = contents()->CreateOpenerRenderViews(
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_rvh->GetSiteInstance());
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should find the pending RVH and not create a new one.
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(pending_rvh->GetRoutingID(), opener_routing_id);
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that WebContentsImpl uses the current URL, not the SiteInstance's site,
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to determine whether a navigation is cross-site.
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteComparesAgainstCurrentPage) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* orig_rvh = rvh();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a related contents to a second site.
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> contents2(
7437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      TestWebContents::Create(browser_context(), instance1));
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->transition_cross_site = true;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->GetController().LoadURL(url2, Referrer(),
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PAGE_TRANSITION_TYPED,
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    std::string());
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first RVH in contents2 isn't live yet, so we shortcut the cross site
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pending.
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh2 = static_cast<TestRenderViewHost*>(
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents2->GetRenderViewHost());
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents2->cross_navigation_pending());
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents2->TestDidNavigate(rvh2, 2, url2, PAGE_TRANSITION_TYPED);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents2->GetSiteInstance();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents2->cross_navigation_pending());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a link click in first contents to second site.  Doesn't switch
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SiteInstances, because we don't intercept WebKit navigations.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      orig_rvh, 2, url2, PAGE_TRANSITION_TYPED);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance3 = contents()->GetSiteInstance();
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, instance3);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to the new site.  Doesn't switch SiteInstancees, because we
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compare against the current URL, not the SiteInstance's site.
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://mail.yahoo.com");
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      orig_rvh, 3, url3, PAGE_TRANSITION_TYPED);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance4 = contents()->GetSiteInstance();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, instance4);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the onbeforeunload and onunload handlers run when navigating
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// across site boundaries.
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteUnloadHandlers) {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site, but simulate an onbeforeunload denial.
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, false, now, now));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate again, but simulate an onbeforeunload approval.
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  now = base::TimeTicks::Now();
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents()->GetPendingRenderViewHost());
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We won't hear DidNavigate until the onunload handler has finished running.
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // DidNavigate from the pending page.
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(pending_rvh, rvh());
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that during a slow cross-site navigation, the original renderer can
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigate to a different URL and have it displayed, canceling the slow
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation.
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteNavigationPreempted) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site, simulating an onbeforeunload approval.
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suppose the original renderer navigates before the new one is ready.
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo"));
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the pending navigation is cancelled.
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, rvh());
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, instance2);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteNavigationBackPreempted) {
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start with a web ui page, which gets a new RVH with WebUI bindings.
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url1("chrome://blah");
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* ntp_rvh = test_rvh();
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(ntp_rvh, 1, url1, PAGE_TRANSITION_TYPED);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry1 = controller().GetLastCommittedEntry();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ntp_rvh, contents()->GetRenderViewHost());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, entry1->GetURL());
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1,
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(entry1)->site_instance());
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ntp_rvh->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.google.com");
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* google_rvh =
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate beforeunload approval.
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ntp_rvh->is_waiting_for_beforeunload_ack());
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ntp_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the pending page.
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_rvh, 1, url2, PAGE_TRANSITION_TYPED);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry2 = controller().GetLastCommittedEntry();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_rvh, contents()->GetRenderViewHost());
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetPendingRenderViewHost());
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, entry2->GetURL());
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance2,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(entry2)->site_instance());
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(google_rvh->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to third page on same site.
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://news.google.com");
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_rvh, 2, url3, PAGE_TRANSITION_TYPED);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry3 = controller().GetLastCommittedEntry();
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance3 = contents()->GetSiteInstance();
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_rvh, contents()->GetRenderViewHost());
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance2, instance3);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetPendingRenderViewHost());
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, entry3->GetURL());
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance3,
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(entry3)->site_instance());
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back within the site.
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().GoBack();
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry2, controller().GetPendingEntry());
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, go back again.
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().GoBack();
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost());
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(entry1, controller().GetPendingEntry());
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate beforeunload approval.
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(google_rvh->is_waiting_for_beforeunload_ack());
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  now = base::TimeTicks::Now();
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  google_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the first back. This aborts the second back's pending RVH.
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(google_rvh, 1, url2, PAGE_TRANSITION_TYPED);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should commit this page and forget about the second back.
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller().GetPendingEntry());
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_rvh, contents()->GetRenderViewHost());
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller().GetLastCommittedEntry()->GetURL());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not have corrupted the NTP entry.
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance3,
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(entry3)->site_instance());
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance2,
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(entry2)->site_instance());
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1,
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(entry1)->site_instance());
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, entry1->GetURL());
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that during a slow cross-site navigation, a sub-frame navigation in the
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// original renderer will not cancel the slow navigation (bug 42029).
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteNavigationNotPreemptedByFrame) {
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start navigating to new site.
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a sub-frame navigation arriving and ensure the RVH is still
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // waiting for a before unload response.
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->SendNavigateWithTransition(1, GURL("http://google.com/frame"),
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       PAGE_TRANSITION_AUTO_SUBFRAME);
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now simulate the onbeforeunload approval and verify the navigation is
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not canceled.
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a cross-site navigation is not preempted if the previous
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// renderer sends a FrameNavigate message just before being told to stop.
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We should only preempt the cross-site navigation if the previous renderer
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// has started a new navigation.  See http://crbug.com/79176.
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteNotPreemptedDuringBeforeUnload) {
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to NTP URL.
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url("chrome://blah");
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site, with the beforeunload request in flight.
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* pending_rvh =
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suppose the first navigation tries to commit now, with a
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ViewMsg_Stop in flight.  This should not cancel the pending navigation,
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but it should act as if the beforeunload ack arrived.
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  orig_rvh->SendNavigate(1, GURL("chrome://blah"));
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pending navigation should be able to commit successfully.
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(pending_rvh, contents()->GetRenderViewHost());
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the original renderer cannot preempt a cross-site navigation once
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the unload request has been made.  At this point, the cross-site navigation
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is almost ready to be displayed, and the original renderer is only given a
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// short chance to run an unload handler.  Prevents regression of bug 23942.
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteCantPreemptAfterUnload) {
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site, simulating an onbeforeunload approval.
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents()->GetPendingRenderViewHost());
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the pending renderer's response, which leads to an unload request
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // being sent to orig_rvh.
10647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
10657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      pending_rvh, GlobalRequestID(0, 0));
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suppose the original renderer navigates now, while the unload request is in
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // flight.  We should ignore it, wait for the unload ack, and let the pending
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request continue.  Otherwise, the contents may close spontaneously or stop
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // responding to navigation requests.  (See bug 23942.)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewHostMsg_FrameNavigate_Params params1a;
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitNavigateParams(&params1a, 2, GURL("http://www.google.com/foo"),
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     PAGE_TRANSITION_TYPED);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo"));
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the pending navigation is still in progress.
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() != NULL);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the pending page should commit it.
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_rvh, 1, url2, PAGE_TRANSITION_TYPED);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(pending_rvh, rvh());
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance1, instance2);
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a cross-site navigation that doesn't commit after the unload
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// handler doesn't leave the contents in a stuck state.  http://crbug.com/88562
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CrossSiteNavigationCanceled) {
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->transition_cross_site = true;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 = contents()->GetSiteInstance();
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  First URL should use first RenderViewHost.
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to new site, simulating an onbeforeunload approval.
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->cross_navigation_pending());
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate swap out message when the response arrives.
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  orig_rvh->set_is_swapped_out(true);
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suppose the navigation doesn't get a chance to commit, and the user
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigates in the current RVH's SiteInstance.
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the pending navigation is cancelled and the renderer is no
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // longer swapped out.
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 = contents()->GetSiteInstance();
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, rvh());
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(orig_rvh->is_swapped_out());
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, instance2);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Test that NavigationEntries have the correct page state after going
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// forward and back.  Prevents regression for bug 1116137.
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NavigationEntryContentState) {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL.  There should be no committed entry yet.
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetLastCommittedEntry();
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry == NULL);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Committed entry should have page state after DidNavigate.
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetLastCommittedEntry();
114590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(entry->GetPageState().IsValid());
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to same site.
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://images.google.com");
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetLastCommittedEntry();
115190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(entry->GetPageState().IsValid());
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Committed entry should have page state after DidNavigate.
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 2, url2, PAGE_TRANSITION_TYPED);
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetLastCommittedEntry();
115690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(entry->GetPageState().IsValid());
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Now go back.  Committed entry should still have page state.
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().GoBack();
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetLastCommittedEntry();
116290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(entry->GetPageState().IsValid());
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Test that NavigationEntries have the correct page state and SiteInstance
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// state after opening a new window to about:blank.  Prevents regression for
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bugs b/1116137 and http://crbug.com/111975.
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* orig_rvh = test_rvh();
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When opening a new window, it is navigated to about:blank internally.
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Currently, this results in two DidNavigate events.
117390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const GURL url(kAboutBlankURL);
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, url, PAGE_TRANSITION_TYPED);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Should have a page state here.
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetLastCommittedEntry();
117990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(entry->GetPageState().IsValid());
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The SiteInstance should be available for other navigations to use.
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry_impl =
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(entry);
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(entry_impl->site_instance()->HasSite());
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 site_instance_id = entry_impl->site_instance()->GetId();
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigating to a normal page should not cause a process swap.
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL new_url("http://www.google.com");
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(new_url, Referrer(),
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PAGE_TRANSITION_TYPED, std::string());
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->cross_navigation_pending());
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(orig_rvh, 1, new_url, PAGE_TRANSITION_TYPED);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry_impl2 = NavigationEntryImpl::FromNavigationEntry(
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      controller().GetLastCommittedEntry());
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(site_instance_id, entry_impl2->site_instance()->GetId());
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry_impl2->site_instance()->HasSite());
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Interstitial Tests
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page (with the navigation initiated from the browser,
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as when a URL is typed in the location bar) that shows an interstitial and
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creates a new navigation entry, then hiding it without proceeding.
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest,
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ShowInterstitialFromBrowserWithNewNavigationDontProceed) {
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a browser navigation that will trigger the interstitial
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(GURL("http://www.evil.com"), Referrer(),
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        PAGE_TRANSITION_TYPED, std::string());
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should not show until its navigation has committed.
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's commit the interstitial navigation.
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url2);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now don't proceed.
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->DontProceed();
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetActiveEntry();
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url1);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page (with the navigation initiated from the renderer,
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as when clicking on a link in the page) that shows an interstitial and
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creates a new navigation entry, then hiding it without proceeding.
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest,
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ShowInterstitiaFromRendererlWithNewNavigationDontProceed) {
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial (no pending entry, the interstitial would have been
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // triggered by clicking on a link).
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should not show until its navigation has committed.
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's commit the interstitial navigation.
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url2);
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now don't proceed.
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->DontProceed();
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetActiveEntry();
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url1);
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial without creating a new
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation entry (this happens when the interstitial is triggered by a
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sub-resource in the page), then hiding it without proceeding.
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialNoNewNavigationDontProceed) {
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), false, url2, &state, &deleted);
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should not show until its navigation has committed.
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's commit the interstitial navigation.
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL specified to the interstitial should have been ignored.
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url1);
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now don't proceed.
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->DontProceed();
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetActiveEntry();
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url1);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page (with the navigation initiated from the browser,
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as when a URL is typed in the location bar) that shows an interstitial and
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creates a new navigation entry, then proceeding.
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest,
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ShowInterstitialFromBrowserNewNavigationProceed) {
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a browser navigation that will trigger the interstitial
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(GURL("http://www.evil.com"), Referrer(),
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        PAGE_TRANSITION_TYPED, std::string());
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should not show until its navigation has committed.
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's commit the interstitial navigation.
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url2);
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then proceed.
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Proceed();
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should show until the new navigation commits.
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::OKED, state);
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the navigation to the page, that's when the interstitial gets
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hidden.
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url3("http://www.thepage.com");
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(2, url3);
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetActiveEntry();
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url3);
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller().GetEntryCount());
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page (with the navigation initiated from the renderer,
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as when clicking on a link in the page) that shows an interstitial and
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// creates a new navigation entry, then proceeding.
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest,
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ShowInterstitialFromRendererNewNavigationProceed) {
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should not show until its navigation has committed.
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's commit the interstitial navigation.
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url2);
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then proceed.
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Proceed();
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should show until the new navigation commits.
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted);
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::OKED, state);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the navigation to the page, that's when the interstitial gets
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hidden.
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url3("http://www.thepage.com");
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(2, url3);
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetActiveEntry();
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url3);
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller().GetEntryCount());
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial without creating a new
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation entry (this happens when the interstitial is triggered by a
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sub-resource in the page), then proceeding.
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialNoNewNavigationProceed) {
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), false, url2, &state, &deleted);
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should not show until its navigation has committed.
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's commit the interstitial navigation.
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->ShowingInterstitialPage());
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == interstitial);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL specified to the interstitial should have been ignored.
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url1);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then proceed.
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Proceed();
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since this is not a new navigation, the previous page is dismissed right
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // away and shows the original page.
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::OKED, state);
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller().GetActiveEntry();
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == url1);
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial, then navigating away.
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialThenNavigate) {
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show interstitial.
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://interstitial");
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url, &state, &deleted);
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url);
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While interstitial showing, navigate to a new URL.
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://www.yahoo.com");
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url2);
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial, then going back.
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialThenGoBack) {
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show interstitial.
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL interstitial_url("http://interstitial");
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, interstitial_url,
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &state, &deleted);
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(2, interstitial_url);
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While the interstitial is showing, go back.
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().GoBack();
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we are back to the original page and that the interstitial is
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // gone.
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry);
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1.spec(), entry->GetURL().spec());
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial, has a renderer crash,
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and then goes back.
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenGoBack) {
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show interstitial.
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL interstitial_url("http://interstitial");
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, interstitial_url,
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &state, &deleted);
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(2, interstitial_url);
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Crash the renderer
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->OnMessageReceived(
15957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ViewHostMsg_RenderProcessGone(
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While the interstitial is showing, go back.
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().GoBack();
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we are back to the original page and that the interstitial is
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // gone.
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry);
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1.spec(), entry->GetURL().spec());
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial, has the renderer crash,
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and then navigates to the interstitial.
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenNavigate) {
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show interstitial.
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL interstitial_url("http://interstitial");
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, interstitial_url,
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &state, &deleted);
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Crash the renderer
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->OnMessageReceived(
16347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ViewHostMsg_RenderProcessGone(
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(2, interstitial_url);
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test navigating to a page that shows an interstitial, then close the
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contents.
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialThenCloseTab) {
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show interstitial.
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://interstitial");
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url, &state, &deleted);
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url);
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now close the contents.
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteContents();
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test navigating to a page that shows an interstitial, then close the
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// contents.
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialThenCloseAndShutdown) {
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Show interstitial.
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestInterstitialPage::InterstitialState state =
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool deleted = false;
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("http://interstitial");
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestInterstitialPage* interstitial =
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new TestInterstitialPage(contents(), true, url, &state, &deleted);
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  interstitial->Show();
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  interstitial->TestDidNavigate(1, url);
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      interstitial->GetRenderViewHostForTesting());
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now close the contents.
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeleteContents();
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Before the interstitial has a chance to process its shutdown task,
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // simulate quitting the browser.  This goes through all processes and
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tells them to destruct.
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rvh->OnMessageReceived(
16867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        ViewHostMsg_RenderProcessGone(0, 0, 0));
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunAllPendingInMessageLoop();
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(deleted);
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that after Proceed is called and an interstitial is still shown, no more
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// commands get executed.
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialProceedMultipleCommands) {
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run a command.
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, interstitial->command_received_count());
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDomOperationResponse("toto");
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, interstitial->command_received_count());
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then proceed.
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Proceed();
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted);
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While the navigation to the new page is pending, send other commands, they
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be ignored.
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDomOperationResponse("hello");
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDomOperationResponse("hi");
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, interstitial->command_received_count());
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test showing an interstitial while another interstitial is already showing.
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialOnInterstitial) {
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL start_url("http://www.google.com");
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, start_url);
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state1 =
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted1 = false;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://interstitial1");
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial1 =
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url1, &state1, &deleted1);
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard1(interstitial1);
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial1->Show();
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial1->TestDidNavigate(1, url1);
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now show another interstitial.
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state2 =
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted2 = false;
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial2");
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial2 =
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state2, &deleted2);
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard2(interstitial2);
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->Show();
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->TestDidNavigate(1, url2);
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Showing interstitial2 should have caused interstitial1 to go away.
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted1);
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted2);
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's make sure interstitial2 is working as intended.
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->Proceed();
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL landing_url("http://www.thepage.com");
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(2, landing_url);
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == landing_url);
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller().GetEntryCount());
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted2);
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test showing an interstitial, proceeding and then navigating to another
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interstitial.
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, ShowInterstitialProceedShowInterstitial) {
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page so we have a navigation entry in the controller.
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL start_url("http://www.google.com");
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, start_url);
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state1 =
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted1 = false;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://interstitial1");
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial1 =
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url1, &state1, &deleted1);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard1(interstitial1);
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial1->Show();
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial1->TestDidNavigate(1, url1);
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Take action.  The interstitial won't be hidden until the navigation is
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // committed.
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial1->Proceed();
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::OKED, state1);
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now show another interstitial (simulating the navigation causing another
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interstitial).
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state2 =
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted2 = false;
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial2");
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial2 =
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state2, &deleted2);
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard2(interstitial2);
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->Show();
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->TestDidNavigate(1, url2);
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Showing interstitial2 should have caused interstitial1 to go away.
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted1);
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted2);
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's make sure interstitial2 is working as intended.
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->Proceed();
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL landing_url("http://www.thepage.com");
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(2, landing_url);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted2);
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->ShowingInterstitialPage());
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(contents()->GetInterstitialPage() == NULL);
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller().GetActiveEntry();
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry != NULL);
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetURL() == landing_url);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller().GetEntryCount());
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that navigating away from an interstitial while it's loading cause it
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not to show.
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NavigateBeforeInterstitialShows) {
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL interstitial_url("http://interstitial");
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, interstitial_url,
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &state, &deleted);
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's simulate a navigation initiated from the browser before the
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interstitial finishes loading.
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com");
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(interstitial->is_showing());
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted);
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's make the interstitial navigation commit.
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, interstitial_url);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After it loaded the interstitial should be gone.
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a new request to show an interstitial while an interstitial is
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pending does not cause problems. htp://crbug/29655 and htp://crbug/9442.
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, TwoQuickInterstitials) {
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL interstitial_url("http://interstitial");
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show a first interstitial.
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state1 =
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted1 = false;
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial1 =
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, interstitial_url,
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &state1, &deleted1);
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard1(interstitial1);
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial1->Show();
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show another interstitial on that same contents before the first one had
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time to load.
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state2 =
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted2 = false;
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial2 =
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, interstitial_url,
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &state2, &deleted2);
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard2(interstitial2);
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->Show();
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first interstitial should have been closed and deleted.
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The 2nd one should still be OK.
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted1);
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(deleted2);
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make the interstitial navigation commit it should be showing.
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->TestDidNavigate(1, interstitial_url);
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(interstitial2, contents()->GetInterstitialPage());
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test showing an interstitial and have its renderer crash.
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, InterstitialCrasher) {
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://interstitial");
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url, &state, &deleted);
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a renderer crash before the interstitial is shown.
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  interstitial->TestRenderViewTerminated(
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should have been dismissed.
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try again but this time crash the intersitial after it was shown.
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial =
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url, &state, &deleted);
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url);
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a renderer crash.
1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  interstitial->TestRenderViewTerminated(
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should have been dismissed.
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that showing an interstitial as a result of a browser initiated
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation while an interstitial is showing does not remove the pending
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entry (see http://crbug.com/9791).
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NewInterstitialDoesNotCancelPendingEntry) {
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kUrl[] = "http://www.badguys.com/";
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kGURL(kUrl);
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a navigation to a page
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->GetController().LoadURL(
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate that navigation triggering an interstitial.
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, kGURL);
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a new navigation from the browser that also triggers an
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interstitial.
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->GetController().LoadURL(
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state2 =
19682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted2 = false;
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial2 =
19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new TestInterstitialPage(contents(), true, kGURL, &state2, &deleted2);
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard2(interstitial2);
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->Show();
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial2->TestDidNavigate(1, kGURL);
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we still have an entry.
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = contents()->GetController().GetPendingEntry();
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry);
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl, entry->GetURL().spec());
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And that the first interstitial is gone, but not the second.
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deleted);
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(deleted2);
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that Javascript messages are not shown while an interstitial is
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// showing.
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, NoJSMessageOnInterstitials) {
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kUrl[] = "http://www.badguys.com/";
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kGURL(kUrl);
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a navigation to a page
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->GetController().LoadURL(
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidNavigate from the page
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->TestDidNavigate(rvh(), 1, kGURL, PAGE_TRANSITION_TYPED);
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate showing an interstitial while the page is showing.
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, kGURL);
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While the interstitial is showing, let's simulate the hidden page
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempting to show a JS message.
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Message* dummy_message = new IPC::Message;
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_suppress_message = false;
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->RunJavaScriptMessage(contents()->GetRenderViewHost(),
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16("This is an informative message"), ASCIIToUTF16("OK"),
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGURL, JAVASCRIPT_MESSAGE_TYPE_ALERT, dummy_message,
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &did_suppress_message);
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(did_suppress_message);
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure that if the source passed to CopyStateFromAndPrune has an
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interstitial it isn't copied over to the destination.
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CopyStateFromAndPruneSourceInterstitial) {
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendNavigate(1, url1);
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller().GetEntryCount());
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a browser navigation that will trigger the interstitial
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller().LoadURL(GURL("http://www.evil.com"), Referrer(),
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        PAGE_TRANSITION_TYPED, std::string());
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
20362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://interstitial");
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url2);
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller().GetEntryCount());
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create another NavigationController.
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url3("http://foo2");
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          other_controller.GetEntryAtIndex(0))->site_instance(), 1,
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller());
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The merged controller should only have two entries: url1 and url2.
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the merged controller shouldn't be showing an interstitial.
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(other_contents->ShowingInterstitialPage());
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Makes sure that CopyStateFromAndPrune cannot be called if the target is
2070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// showing an interstitial.
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WebContentsImplTest, CopyStateFromAndPruneTargetInterstitial) {
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a page.
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.google.com");
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->NavigateAndCommit(url1);
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create another NavigationController.
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate it to url2.
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://foo2");
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->NavigateAndCommit(url2);
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show an interstitial.
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage::InterstitialState state =
20872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestInterstitialPage::INVALID;
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url3("http://interstitial");
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPage* interstitial =
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new TestInterstitialPage(other_contents.get(), true, url3, &state,
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &deleted);
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInterstitialPageStateGuard state_guard(interstitial);
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->Show();
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial->TestDidNavigate(1, url3);
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(interstitial->is_showing());
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, other_controller.GetEntryCount());
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Ensure that we do not allow calling CopyStateFromAndPrune when an
2100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // interstitial is showing in the target.
2101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(other_controller.CanPruneAllButVisible());
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Regression test for http://crbug.com/168611 - the URLs passed by the
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DidFinishLoad and DidFailLoadWithError IPCs should get filtered.
21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WebContentsImplTest, FilterURLs) {
21072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestWebContentsObserver observer(contents());
21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A navigation to about:whatever should always look like a navigation to
21102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // about:blank
21112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  GURL url_normalized(kAboutBlankURL);
21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url_from_ipc("about:whatever");
21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We navigate the test WebContents to about:blank, since NavigateAndCommit
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will use the given URL to create the NavigationEntry as well, and that
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // entry should contain the filtered URL.
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->NavigateAndCommit(url_normalized);
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that an IPC with about:whatever is correctly normalized.
21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->TestDidFinishLoad(1, url_from_ipc, true);
21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url_normalized, observer.last_url());
21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create and navigate another WebContents.
21252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
21272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestWebContentsObserver other_observer(other_contents.get());
21282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  other_contents->NavigateAndCommit(url_normalized);
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that an IPC with about:whatever is correctly normalized.
21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  other_contents->TestDidFailLoadWithError(
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      1, url_from_ipc, true, 1, string16());
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(url_normalized, other_observer.last_url());
21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that if a pending contents is deleted before it is shown, we don't
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// crash.
21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WebContentsImplTest, PendingContents) {
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->AddPendingContents(other_contents.get());
21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int route_id = other_contents->GetRenderViewHost()->GetRoutingID();
21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  other_contents.reset();
21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(NULL, contents()->GetCreatedWindow(route_id));
21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// This test asserts the shape of the frame tree is correct, based on incoming
2148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// frame attached/detached messages.
2149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TEST_F(WebContentsImplTest, FrameTreeShape) {
2150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string no_children_node("no children node");
2151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string deep_subtree("node with deep subtree");
2152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The initial navigation will create a frame_tree_root_ node with the top
2154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // level frame id. Simulate that by just creating it here.
2155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->frame_tree_root_.reset(
2156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FrameTreeNode(5, std::string("top-level")));
2157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Let's send a series of messages for frame attached and build the
2159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // frame tree.
2160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(5, 14, std::string());
2161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(5, 15, std::string());
2162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(5, 16, std::string());
2163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(14, 244, std::string());
2165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(14, 245, std::string());
2166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(15, 255, no_children_node);
2168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(16, 264, std::string());
2170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(16, 265, std::string());
2171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(16, 266, std::string());
2172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(16, 267, deep_subtree);
2173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(16, 268, std::string());
2174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2175b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(267, 365, std::string());
2176b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(365, 455, std::string());
2177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(455, 555, std::string());
2178b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameAttached(555, 655, std::string());
2179b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Now, verify the tree structure is as expected.
2181b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FrameTreeNode* root = contents()->frame_tree_root_.get();
2182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(5, root->frame_id());
2183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(3UL, root->child_count());
2184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(2UL, root->child_at(0)->child_count());
2186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(0)->child_at(0)->child_count());
2187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(0)->child_at(1)->child_count());
2188b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2189b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1UL, root->child_at(1)->child_count());
2190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(1)->child_at(0)->child_count());
2191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_STREQ(no_children_node.c_str(),
2192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      root->child_at(1)->child_at(0)->frame_name().c_str());
2193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(5UL, root->child_at(2)->child_count());
2195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(2)->child_at(0)->child_count());
2196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(2)->child_at(1)->child_count());
2197b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(2)->child_at(2)->child_count());
2198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1UL, root->child_at(2)->child_at(3)->child_count());
2199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_STREQ(deep_subtree.c_str(),
2200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      root->child_at(2)->child_at(3)->frame_name().c_str());
2201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, root->child_at(2)->child_at(4)->child_count());
2202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FrameTreeNode* deep_tree = root->child_at(2)->child_at(3)->child_at(0);
2204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(365, deep_tree->frame_id());
2205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1UL, deep_tree->child_count());
2206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(455, deep_tree->child_at(0)->frame_id());
2207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1UL, deep_tree->child_at(0)->child_count());
2208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(555, deep_tree->child_at(0)->child_at(0)->frame_id());
2209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1UL, deep_tree->child_at(0)->child_at(0)->child_count());
2210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(655, deep_tree->child_at(0)->child_at(0)->child_at(0)->frame_id());
2211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL,
2212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      deep_tree->child_at(0)->child_at(0)->child_at(0)->child_count());
2213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Test removing of nodes.
2215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameDetached(555, 655);
2216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0UL, deep_tree->child_at(0)->child_at(0)->child_count());
2217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameDetached(16, 265);
2219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(4UL, root->child_at(2)->child_count());
2220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  contents()->OnFrameDetached(5, 15);
2222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(2UL, root->child_count());
2223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
2224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
2226