1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <vector>
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_value_store.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/test/testing_pref_service.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host_view.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/test_render_view_host.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/site_instance.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/constrained_window.h"
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/interstitial_page.h"
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h"
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/test_tab_contents.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/bindings_policy.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/view_messages.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "ipc/ipc_channel.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/message_box_flags.h"
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "webkit/glue/webkit_glue.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::PasswordForm;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               int page_id,
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               const GURL& url) {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->page_id = page_id;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->url = url;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->referrer = GURL();
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->transition = PageTransition::TYPED;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->redirects = std::vector<GURL>();
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->should_update_history = false;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->searchable_form_url = GURL();
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->searchable_form_encoding = std::string();
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->password_form = PasswordForm();
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->security_info = std::string();
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->gesture = NavigationGestureUser;
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  params->was_within_same_page = false;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params->is_post = false;
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  params->content_state = webkit_glue::CreateHistoryStateForURL(GURL(url));
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestInterstitialPage : public InterstitialPage {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum InterstitialState {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UNDECIDED = 0, // No decision taken yet.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    OKED,          // Proceed was called.
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CANCELED       // DontProceed was called.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Delegate {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void TestInterstitialPageDeleted(
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        TestInterstitialPage* interstitial) = 0;
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick   protected:
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual ~Delegate() {}
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IMPORTANT NOTE: if you pass stack allocated values for |state| and
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |deleted| (like all interstitial related tests do at this point), make sure
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to create an instance of the TestInterstitialPageStateGuard class on the
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // stack in your test.  This will ensure that the TestInterstitialPage states
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are cleared when the test finishes.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Not doing so will cause stack trashing if your test does not hide the
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // interstitial, as in such a case it will be destroyed in the test TearDown
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // method and will dereference the |deleted| local variable which by then is
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // out of scope.
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage(TabContents* tab,
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       bool new_navigation,
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const GURL& url,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       InterstitialState* state,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       bool* deleted)
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : InterstitialPage(tab, new_navigation, url),
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        state_(state),
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        deleted_(deleted),
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        command_received_count_(0),
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        delegate_(NULL) {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *state_ = UNDECIDED;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *deleted_ = false;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~TestInterstitialPage() {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (deleted_)
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *deleted_ = true;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (delegate_)
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      delegate_->TestInterstitialPageDeleted(this);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void DontProceed() {
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (state_)
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *state_ = CANCELED;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InterstitialPage::DontProceed();
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Proceed() {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (state_)
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *state_ = OKED;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InterstitialPage::Proceed();
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_received_count() const {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return command_received_count_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TestDomOperationResponse(const std::string& json_string) {
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DomOperationResponse(json_string, 1);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TestDidNavigate(int page_id, const GURL& url) {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ViewHostMsg_FrameNavigate_Params params;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InitNavigateParams(&params, page_id, url);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DidNavigate(render_view_host(), params);
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void TestRenderViewGone(base::TerminationStatus status, int error_code) {
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RenderViewGone(render_view_host(), status, error_code);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_showing() const {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return static_cast<TestRenderWidgetHostView*>(render_view_host()->view())->
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        is_showing();
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ClearStates() {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    state_ = NULL;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    deleted_ = NULL;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_ = NULL;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_delegate(Delegate* delegate) {
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_ = delegate;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual RenderViewHost* CreateRenderViewHost() {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return new TestRenderViewHost(
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SiteInstance::CreateSiteInstance(tab()->profile()),
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        this, MSG_ROUTING_NONE);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual TabContentsView* CreateTabContentsView() { return NULL; }
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void CommandReceived(const std::string& command) {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    command_received_count_++;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InterstitialState* state_;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool* deleted_;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_received_count_;
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Delegate* delegate_;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestInterstitialPageStateGuard : public TestInterstitialPage::Delegate {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit TestInterstitialPageStateGuard(
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage* interstitial_page)
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : interstitial_page_(interstitial_page) {
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(interstitial_page_);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    interstitial_page_->set_delegate(this);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~TestInterstitialPageStateGuard() {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (interstitial_page_)
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      interstitial_page_->ClearStates();
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TestInterstitialPageDeleted(TestInterstitialPage* interstitial) {
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(interstitial_page_ == interstitial);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    interstitial_page_ = NULL;
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial_page_;
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TabContentsTest : public RenderViewHostTestHarness {
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContentsTest()
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : RenderViewHostTestHarness(),
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        ui_thread_(BrowserThread::UI, &message_loop_) {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Supply our own profile so we use the correct profile data. The test harness
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is not supposed to overwrite a profile if it's already created.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestingProfile* profile = new TestingProfile();
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_.reset(profile);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Set some (WebKit) user preferences.
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TestingPrefService* pref_services = profile->GetTestingPrefService();
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_USES_GTK)
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref_services->SetUserPref(prefs::kUsesSystemTheme,
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Value::CreateBooleanValue(false));
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref_services->SetUserPref(prefs::kDefaultCharset,
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Value::CreateStringValue("utf8"));
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref_services->SetUserPref(prefs::kWebKitDefaultFontSize,
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Value::CreateIntegerValue(20));
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref_services->SetUserPref(prefs::kWebKitTextAreasAreResizable,
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Value::CreateBooleanValue(false));
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref_services->SetUserPref(prefs::kWebKitUsesUniversalDetector,
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Value::CreateBooleanValue(true));
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    pref_services->SetUserPref("webkit.webprefs.foo",
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               Value::CreateStringValue("bar"));
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHostTestHarness::SetUp();
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHostTestHarness::TearDown();
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_.reset(NULL);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread ui_thread_;
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test to make sure that title updates get stripped of whitespace.
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, UpdateTitle) {
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params;
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params, 0, GURL(chrome::kAboutBlankURL));
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController::LoadCommittedDetails details;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().RendererDidNavigate(params, 0, &details);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->UpdateTitle(rvh(), 0, L"    Lots O' Whitespace\n");
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("Lots O' Whitespace"), contents()->GetTitle());
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test view source mode for the new tabs page.
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NTPViewSource) {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kUrl[] = "view-source:chrome://newtab";
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL kGURL(kUrl);
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  process()->sink().ClearMessages();
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(kGURL, GURL(), PageTransition::TYPED);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->delegate()->RenderViewCreated(rvh());
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Did we get the expected message?
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(process()->sink().GetFirstMessageMatching(
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ViewMsg_EnableViewSourceMode::ID));
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params;
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params, 0, kGURL);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController::LoadCommittedDetails details;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().RendererDidNavigate(params, 0, &details);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Also check title and url.
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16(kUrl), contents()->GetTitle());
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(contents()->ShouldDisplayURL());
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test simple same-SiteInstance navigation.
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, SimpleNavigation) {
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, orig_rvh->site_instance());
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Controller's pending entry will have a NULL site instance until we assign
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it in DidNavigate.
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(controller().GetActiveEntry()->site_instance() == NULL);
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the page
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params;
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params, 1, url);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params);
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, orig_rvh->site_instance());
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Controller's entry should now have the SiteInstance, or else we won't be
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // able to find it later.
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, controller().GetActiveEntry()->site_instance());
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that navigating across a site boundary creates a new RenderViewHost
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// with a new SiteInstance.  Going back should do the same.
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteBoundaries) {
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int orig_rvh_delete_count = 0;
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->set_delete_counter(&orig_rvh_delete_count);
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to new site
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* pending_rvh = contents()->pending_rvh();
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pending_rvh_delete_count = 0;
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_rvh->set_delete_counter(&pending_rvh_delete_count);
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the pending page
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2;
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2, 1, url2);
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(pending_rvh, params2);
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2 = contents()->GetSiteInstance();
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(pending_rvh, contents()->render_view_host());
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2);
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh_delete_count, 1);
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Going back should switch SiteInstances again.  The first SiteInstance is
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // stored in the NavigationEntry, so it should be the same as at the start.
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().GoBack();
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* goback_rvh = contents()->pending_rvh();
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the back action
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(goback_rvh, params1);
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(goback_rvh, contents()->render_view_host());
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(pending_rvh_delete_count, 1);
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, contents()->GetSiteInstance());
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that navigating across a site boundary after a crash creates a new
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RVH without requiring a cross-site transition (i.e., PENDING state).
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteBoundariesAfterCrash) {
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int orig_rvh_delete_count = 0;
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->set_delete_counter(&orig_rvh_delete_count);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Crash the renderer.
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->set_render_view_created(false);
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to new site.  We should not go into PENDING.
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* new_rvh = rvh();
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(orig_rvh, new_rvh);
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh_delete_count, 1);
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the new page
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2, 1, url2);
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(new_rvh, params2);
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2 = contents()->GetSiteInstance();
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(new_rvh, rvh());
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that opening a new tab in the same SiteInstance and then navigating
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// both tabs to a new site will place both tabs in a single SiteInstance.
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NavigateTwoTabsCrossSite) {
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a new tab with the same SiteInstance, navigated to the same site.
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestTabContents contents2(profile(), instance1);
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  params1.page_id = 2;  // Need this since the site instance is the same (which
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        // is the scope of page IDs) and we want to consider
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        // this a new page.
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.transition_cross_site = true;
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.controller().LoadURL(url, GURL(), PageTransition::TYPED);
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.TestDidNavigate(contents2.render_view_host(), params1);
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate first tab to a new site
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2a("http://www.yahoo.com");
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2a, GURL(), PageTransition::TYPED);
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* pending_rvh_a = contents()->pending_rvh();
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2a;
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2a, 1, url2a);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(pending_rvh_a, params2a);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2a = contents()->GetSiteInstance();
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2a);
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate second tab to the same site as the first tab
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2b("http://mail.yahoo.com");
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.controller().LoadURL(url2b, GURL(), PageTransition::TYPED);
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* pending_rvh_b = contents2.pending_rvh();
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pending_rvh_b != NULL);
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents2.cross_navigation_pending());
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NOTE(creis): We used to be in danger of showing a sad tab page here if the
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // second tab hadn't navigated somewhere first (bug 1145430).  That case is
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // now covered by the CrossSiteBoundariesAfterCrash test.
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2b;
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2b, 2, url2b);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.TestDidNavigate(pending_rvh_b, params2b);
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2b = contents2.GetSiteInstance();
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2b);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Both tabs should now be in the same SiteInstance.
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance2a, instance2b);
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that TabContents uses the current URL, not the SiteInstance's site, to
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// determine whether a navigation is cross-site.
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteComparesAgainstCurrentPage) {
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a related tab to a second site.
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestTabContents contents2(profile(), instance1);
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.transition_cross_site = true;
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.controller().LoadURL(url2, GURL(), PageTransition::TYPED);
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The first RVH in contents2 isn't live yet, so we shortcut the cross site
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pending.
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* rvh2 = static_cast<TestRenderViewHost*>(
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents2.render_view_host());
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents2.cross_navigation_pending());
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2;
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2, 2, url2);
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2.TestDidNavigate(rvh2, params2);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2 = contents2.GetSiteInstance();
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2);
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents2.cross_navigation_pending());
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate a link click in first tab to second site.  Doesn't switch
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SiteInstances, because we don't intercept WebKit navigations.
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params3;
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params3, 2, url2);
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params3);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance3 = contents()->GetSiteInstance();
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, instance3);
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to the new site.  Doesn't switch SiteInstancees, because we
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // compare against the current URL, not the SiteInstance's site.
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url3("http://mail.yahoo.com");
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url3, GURL(), PageTransition::TYPED);
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params4;
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params4, 3, url3);
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params4);
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance4 = contents()->GetSiteInstance();
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, instance4);
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the onbeforeunload and onunload handlers run when navigating
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// across site boundaries.
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteUnloadHandlers) {
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to new site, but simulate an onbeforeunload denial.
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, false));
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate again, but simulate an onbeforeunload approval.
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents()->pending_rvh());
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We won't hear DidNavigate until the onunload handler has finished running.
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (No way to simulate that here, but it involves a call from RDH to
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents::OnCrossSiteResponse.)
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the pending page
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2;
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2, 1, url2);
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(pending_rvh, params2);
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2 = contents()->GetSiteInstance();
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(pending_rvh, rvh());
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2);
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that during a slow cross-site navigation, the original renderer can
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// navigate to a different URL and have it displayed, canceling the slow
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// navigation.
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteNavigationPreempted) {
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to new site, simulating an onbeforeunload approval.
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Suppose the original renderer navigates before the new one is ready.
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo"));
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify that the pending navigation is cancelled.
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2 = contents()->GetSiteInstance();
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, rvh());
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(instance1, instance2);
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabContentsTest, CrossSiteNavigationBackPreempted) {
581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents()->transition_cross_site = true;
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Start with NTP, which gets a new RVH with WebUI bindings.
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const GURL url1("chrome://newtab");
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  controller().LoadURL(url1, GURL(), PageTransition::TYPED);
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TestRenderViewHost* ntp_rvh = rvh();
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ViewHostMsg_FrameNavigate_Params params1;
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitNavigateParams(&params1, 1, url1);
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents()->TestDidNavigate(ntp_rvh, params1);
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NavigationEntry* entry1 = controller().GetLastCommittedEntry();
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SiteInstance* instance1 = contents()->GetSiteInstance();
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->cross_navigation_pending());
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(ntp_rvh, contents()->render_view_host());
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(url1, entry1->url());
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance1, entry1->site_instance());
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(BindingsPolicy::is_web_ui_enabled(ntp_rvh->enabled_bindings()));
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Navigate to new site.
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const GURL url2("http://www.google.com");
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(contents()->cross_navigation_pending());
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TestRenderViewHost* google_rvh = contents()->pending_rvh();
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Simulate beforeunload approval.
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(ntp_rvh->is_waiting_for_beforeunload_ack());
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ntp_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DidNavigate from the pending page.
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ViewHostMsg_FrameNavigate_Params params2;
611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitNavigateParams(&params2, 1, url2);
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents()->TestDidNavigate(google_rvh, params2);
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NavigationEntry* entry2 = controller().GetLastCommittedEntry();
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SiteInstance* instance2 = contents()->GetSiteInstance();
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->cross_navigation_pending());
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(google_rvh, contents()->render_view_host());
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_NE(instance1, instance2);
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->pending_rvh());
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(url2, entry2->url());
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance2, entry2->site_instance());
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(BindingsPolicy::is_web_ui_enabled(
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      google_rvh->enabled_bindings()));
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Navigate to third page on same site.
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const GURL url3("http://news.google.com");
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  controller().LoadURL(url3, GURL(), PageTransition::TYPED);
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->cross_navigation_pending());
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ViewHostMsg_FrameNavigate_Params params3;
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitNavigateParams(&params3, 2, url3);
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents()->TestDidNavigate(google_rvh, params3);
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NavigationEntry* entry3 = controller().GetLastCommittedEntry();
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SiteInstance* instance3 = contents()->GetSiteInstance();
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->cross_navigation_pending());
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(google_rvh, contents()->render_view_host());
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance2, instance3);
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->pending_rvh());
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(url3, entry3->url());
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance3, entry3->site_instance());
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Go back within the site.
643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  controller().GoBack();
644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->cross_navigation_pending());
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(entry2, controller().pending_entry());
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Before that commits, go back again.
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  controller().GoBack();
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(contents()->cross_navigation_pending());
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(contents()->pending_rvh());
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(entry1, controller().pending_entry());
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Simulate beforeunload approval.
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(google_rvh->is_waiting_for_beforeunload_ack());
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  google_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DidNavigate from the first back. This aborts the second back's pending RVH.
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents()->TestDidNavigate(google_rvh, params2);
659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We should commit this page and forget about the second back.
661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(contents()->cross_navigation_pending());
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(controller().pending_entry());
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(google_rvh, contents()->render_view_host());
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(url2, controller().GetLastCommittedEntry()->url());
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We should not have corrupted the NTP entry.
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance3, entry3->site_instance());
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance2, entry2->site_instance());
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(instance1, entry1->site_instance());
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(url1, entry1->url());
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that during a slow cross-site navigation, a sub-frame navigation in the
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// original renderer will not cancel the slow navigation (bug 42029).
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteNavigationNotPreemptedByFrame) {
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start navigating to new site.
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate a sub-frame navigation arriving and ensure the RVH is still
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // waiting for a before unload response.
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->SendNavigateWithTransition(1, GURL("http://google.com/frame"),
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       PageTransition::AUTO_SUBFRAME);
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now simulate the onbeforeunload approval and verify the navigation is
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // not canceled.
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7053dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen// Test that a cross-site navigation is not preempted if the previous
7063dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen// renderer sends a FrameNavigate message just before being told to stop.
7073dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen// We should only preempt the cross-site navigation if the previous renderer
7083dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen// has started a new navigation.  See http://crbug.com/79176.
7093dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian MonsenTEST_F(TabContentsTest, CrossSiteNotPreemptedDuringBeforeUnload) {
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7123dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  // Navigate to NTP URL.
7133dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  const GURL url("chrome://newtab");
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
7153dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  TestRenderViewHost* orig_rvh = rvh();
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7183dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  // Navigate to new site, with the beforeunload request in flight.
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
7213dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  TestRenderViewHost* pending_rvh = contents()->pending_rvh();
7223dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  EXPECT_TRUE(contents()->cross_navigation_pending());
7233dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7253dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  // Suppose the first navigation tries to commit now, with a
7263dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  // ViewMsg_Stop in flight.  This should not cancel the pending navigation,
7273dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  // but it should act as if the beforeunload ack arrived.
7283dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  orig_rvh->SendNavigate(1, GURL("chrome://newtab"));
7293dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  EXPECT_TRUE(contents()->cross_navigation_pending());
7303dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  EXPECT_EQ(orig_rvh, contents()->render_view_host());
7313dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7333dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  // The pending navigation should be able to commit successfully.
7343dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  ViewHostMsg_FrameNavigate_Params params2;
7353dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  InitNavigateParams(&params2, 1, url2, PageTransition::TYPED);
7363dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  contents()->TestDidNavigate(pending_rvh, params2);
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
7383dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  EXPECT_EQ(pending_rvh, contents()->render_view_host());
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that the original renderer cannot preempt a cross-site navigation once
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the unload request has been made.  At this point, the cross-site navigation
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is almost ready to be displayed, and the original renderer is only given a
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// short chance to run an unload handler.  Prevents regression of bug 23942.
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, CrossSiteCantPreemptAfterUnload) {
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->transition_cross_site = true;
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance1 = contents()->GetSiteInstance();
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  First URL should use first RenderViewHost.
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(orig_rvh, contents()->render_view_host());
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to new site, simulating an onbeforeunload approval.
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true));
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents()->pending_rvh());
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate the pending renderer's response, which leads to an unload request
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // being sent to orig_rvh.
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->OnCrossSiteResponse(0, 0);
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Suppose the original renderer navigates now, while the unload request is in
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // flight.  We should ignore it, wait for the unload ack, and let the pending
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // request continue.  Otherwise, the tab may close spontaneously or stop
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // responding to navigation requests.  (See bug 23942.)
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1a;
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1a, 2, GURL("http://www.google.com/foo"));
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo"));
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify that the pending navigation is still in progress.
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->cross_navigation_pending());
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() != NULL);
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the pending page should commit it.
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2;
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2, 1, url2);
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(pending_rvh, params2);
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SiteInstance* instance2 = contents()->GetSiteInstance();
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->cross_navigation_pending());
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(pending_rvh, rvh());
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(instance1, instance2);
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->pending_rvh() == NULL);
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that NavigationEntries have the correct content state after going
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// forward and back.  Prevents regression for bug 1116137.
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NavigationEntryContentState) {
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to URL.  There should be no committed entry yet.
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetLastCommittedEntry();
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry == NULL);
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Committed entry should have content state after DidNavigate.
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetLastCommittedEntry();
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(entry->content_state().empty());
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to same site.
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://images.google.com");
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url2, GURL(), PageTransition::TYPED);
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetLastCommittedEntry();
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(entry->content_state().empty());
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Committed entry should have content state after DidNavigate.
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params2;
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params2, 2, url2);
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params2);
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetLastCommittedEntry();
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(entry->content_state().empty());
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now go back.  Committed entry should still have content state.
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().GoBack();
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetLastCommittedEntry();
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(entry->content_state().empty());
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that NavigationEntries have the correct content state after opening
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a new window to about:blank.  Prevents regression for bug 1116137.
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NavigationEntryContentStateNewWindow) {
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestRenderViewHost* orig_rvh = rvh();
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When opening a new window, it is navigated to about:blank internally.
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Currently, this results in two DidNavigate events.
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url(chrome::kAboutBlankURL);
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params1;
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params1, 1, url);
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(orig_rvh, params1);
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Should have a content state here.
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetLastCommittedEntry();
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(entry->content_state().empty());
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests to see that webkit preferences are properly loaded and copied over
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to a WebPreferences object.
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, WebKitPrefs) {
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebPreferences webkit_prefs = contents()->TestGetWebkitPrefs();
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These values have been overridden by the profile preferences.
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("UTF-8", webkit_prefs.default_encoding);
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(20, webkit_prefs.default_font_size);
858731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(webkit_prefs.text_areas_are_resizable);
859731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(webkit_prefs.uses_universal_detector);
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These should still be the default values.
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
86321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const char kDefaultFont[] = "Times";
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_CHROMEOS)
86521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const char kDefaultFont[] = "Tinos";
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
86721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const char kDefaultFont[] = "Times New Roman";
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
86921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(ASCIIToUTF16(kDefaultFont), webkit_prefs.standard_font_family);
870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(webkit_prefs.javascript_enabled);
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Interstitial Tests
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page (with the navigation initiated from the browser,
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// as when a URL is typed in the location bar) that shows an interstitial and
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// creates a new navigation entry, then hiding it without proceeding.
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest,
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ShowInterstitialFromBrowserWithNewNavigationDontProceed) {
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page.
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initiate a browser navigation that will trigger the interstitial
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(GURL("http://www.evil.com"), GURL(),
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        PageTransition::TYPED);
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should not show until its navigation has committed.
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's commit the interstitial navigation.
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial->is_showing());
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url2);
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now don't proceed.
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->DontProceed();
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetActiveEntry();
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url1);
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page (with the navigation initiated from the renderer,
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// as when clicking on a link in the page) that shows an interstitial and
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// creates a new navigation entry, then hiding it without proceeding.
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest,
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ShowInterstitiaFromRendererlWithNewNavigationDontProceed) {
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page.
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial (no pending entry, the interstitial would have been
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // triggered by clicking on a link).
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should not show until its navigation has committed.
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's commit the interstitial navigation.
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial->is_showing());
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url2);
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now don't proceed.
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->DontProceed();
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetActiveEntry();
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url1);
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial without creating a new
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// navigation entry (this happens when the interstitial is triggered by a
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sub-resource in the page), then hiding it without proceeding.
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialNoNewNavigationDontProceed) {
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page.
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), false, url2, &state, &deleted);
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should not show until its navigation has committed.
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's commit the interstitial navigation.
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial->is_showing());
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The URL specified to the interstitial should have been ignored.
1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url1);
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now don't proceed.
1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->DontProceed();
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetActiveEntry();
1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url1);
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page (with the navigation initiated from the browser,
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// as when a URL is typed in the location bar) that shows an interstitial and
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// creates a new navigation entry, then proceeding.
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest,
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ShowInterstitialFromBrowserNewNavigationProceed) {
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page.
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initiate a browser navigation that will trigger the interstitial
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(GURL("http://www.evil.com"), GURL(),
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        PageTransition::TYPED);
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should not show until its navigation has committed.
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's commit the interstitial navigation.
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial->is_showing());
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url2);
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then proceed.
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Proceed();
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should show until the new navigation commits.
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deleted);
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::OKED, state);
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate the navigation to the page, that's when the interstitial gets
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // hidden.
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url3("http://www.thepage.com");
1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(2, url3);
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetActiveEntry();
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url3);
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, controller().entry_count());
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page (with the navigation initiated from the renderer,
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// as when clicking on a link in the page) that shows an interstitial and
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// creates a new navigation entry, then proceeding.
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest,
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ShowInterstitialFromRendererNewNavigationProceed) {
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page.
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should not show until its navigation has committed.
1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's commit the interstitial navigation.
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial->is_showing());
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url2);
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then proceed.
1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Proceed();
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should show until the new navigation commits.
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deleted);
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::OKED, state);
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate the navigation to the page, that's when the interstitial gets
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // hidden.
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url3("http://www.thepage.com");
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(2, url3);
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetActiveEntry();
1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url3);
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, controller().entry_count());
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial without creating a new
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// navigation entry (this happens when the interstitial is triggered by a
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sub-resource in the page), then proceeding.
1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialNoNewNavigationProceed) {
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), false, url2, &state, &deleted);
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should not show until its navigation has committed.
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's commit the interstitial navigation.
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial->is_showing());
1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->showing_interstitial_page());
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == interstitial);
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The URL specified to the interstitial should have been ignored.
1158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url1);
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then proceed.
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Proceed();
1162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Since this is not a new navigation, the previous page is dismissed right
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // away and shows the original page.
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::OKED, state);
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entry = controller().GetActiveEntry();
1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == url1);
1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial, then navigating away.
1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialThenNavigate) {
1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show interstitial.
1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("http://interstitial");
1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url, &state, &deleted);
1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url);
1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // While interstitial showing, navigate to a new URL.
1189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url2("http://www.yahoo.com");
1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url2);
1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial, then going back.
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialThenGoBack) {
1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show interstitial.
1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL interstitial_url("http://interstitial");
1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, interstitial_url,
1210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &state, &deleted);
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(2, interstitial_url);
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // While the interstitial is showing, go back.
1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().GoBack();
1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we are back to the original page and that the interstitial is
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // gone.
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry);
1225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(url1.spec(), entry->url().spec());
1226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial, has a renderer crash,
1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and then goes back.
1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialCrashRendererThenGoBack) {
1231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show interstitial.
1237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL interstitial_url("http://interstitial");
1241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, interstitial_url,
1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &state, &deleted);
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(2, interstitial_url);
1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Crash the renderer
124921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  rvh()->TestOnMessageReceived(
125021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ViewHostMsg_RenderViewGone(
125121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // While the interstitial is showing, go back.
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().GoBack();
1255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we are back to the original page and that the interstitial is
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // gone.
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry);
1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(url1.spec(), entry->url().spec());
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial, has the renderer crash,
1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and then navigates to the interstitial.
1268c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialCrashRendererThenNavigate) {
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show interstitial.
1275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL interstitial_url("http://interstitial");
1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, interstitial_url,
1281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &state, &deleted);
1282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Crash the renderer
128621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  rvh()->TestOnMessageReceived(
128721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ViewHostMsg_RenderViewGone(
128821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1));
1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(2, interstitial_url);
1291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test navigating to a page that shows an interstitial, then close the tab.
1294c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialThenCloseTab) {
1295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show interstitial.
1296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("http://interstitial");
1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url, &state, &deleted);
1302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url);
1305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now close the tab.
1307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DeleteContents();
1308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that after Proceed is called and an interstitial is still shown, no more
1313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// commands get executed.
1314c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialProceedMultipleCommands) {
1315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.google.com");
1317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, url1);
1318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial");
1325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
1327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url2);
1330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Run a command.
1332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, interstitial->command_received_count());
1333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDomOperationResponse("toto");
1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, interstitial->command_received_count());
1335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then proceed.
1337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Proceed();
1338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deleted);
1339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // While the navigation to the new page is pending, send other commands, they
1341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be ignored.
1342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDomOperationResponse("hello");
1343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDomOperationResponse("hi");
1344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, interstitial->command_received_count());
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test showing an interstitial while another interstitial is already showing.
1348c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialOnInterstitial) {
1349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL start_url("http://www.google.com");
1351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, start_url);
1352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state1 =
1356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted1 = false;
1358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://interstitial1");
1359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial1 =
1360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url1, &state1, &deleted1);
1361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard1(interstitial1);
1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial1->Show();
1363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial1->TestDidNavigate(1, url1);
1364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now show another interstitial.
1366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state2 =
1367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted2 = false;
1369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial2");
1370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial2 =
1371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state2, &deleted2);
1372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard2(interstitial2);
1373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->Show();
1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->TestDidNavigate(1, url2);
1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Showing interstitial2 should have caused interstitial1 to go away.
1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted1);
1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's make sure interstitial2 is working as intended.
1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deleted2);
1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
1383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->Proceed();
1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL landing_url("http://www.thepage.com");
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(2, landing_url);
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted2);
1388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == landing_url);
1393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, controller().entry_count());
1394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test showing an interstitial, proceeding and then navigating to another
1397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// interstitial.
1398c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, ShowInterstitialProceedShowInterstitial) {
1399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate to a page so we have a navigation entry in the controller.
1400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL start_url("http://www.google.com");
1401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(1, start_url);
1402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, controller().entry_count());
1403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state1 =
1406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted1 = false;
1408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://interstitial1");
1409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial1 =
1410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url1, &state1, &deleted1);
1411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard1(interstitial1);
1412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial1->Show();
1413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial1->TestDidNavigate(1, url1);
1414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Take action.  The interstitial won't be hidden until the navigation is
1416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // committed.
1417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial1->Proceed();
1418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::OKED, state1);
1419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now show another interstitial (simulating the navigation causing another
1421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // interstitial).
1422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state2 =
1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted2 = false;
1425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://interstitial2");
1426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial2 =
1427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url2, &state2, &deleted2);
1428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard2(interstitial2);
1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->Show();
1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->TestDidNavigate(1, url2);
1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Showing interstitial2 should have caused interstitial1 to go away.
1433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted1);
1434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's make sure interstitial2 is working as intended.
1436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deleted2);
1437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
1438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->Proceed();
1439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL landing_url("http://www.thepage.com");
1440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rvh()->SendNavigate(2, landing_url);
1441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted2);
1443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(contents()->showing_interstitial_page());
1444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(contents()->interstitial_page() == NULL);
1445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller().GetActiveEntry();
1446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry != NULL);
1447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entry->url() == landing_url);
1448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, controller().entry_count());
1449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that navigating away from an interstitial while it's loading cause it
1452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// not to show.
1453c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NavigateBeforeInterstitialShows) {
1454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL interstitial_url("http://interstitial");
1459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, interstitial_url,
1461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &state, &deleted);
1462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's simulate a navigation initiated from the browser before the
1466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // interstitial finishes loading.
1467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL url("http://www.google.com");
1468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller().LoadURL(url, GURL(), PageTransition::TYPED);
1469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deleted);
1470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(interstitial->is_showing());
1471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now let's make the interstitial navigation commit.
1473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, interstitial_url);
1474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // After it loaded the interstitial should be gone.
1476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that a new request to show an interstitial while an interstitial is
14813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// pending does not cause problems. htp://crbug/29655 and htp://crbug/9442.
14823345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(TabContentsTest, TwoQuickInterstitials) {
14833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL interstitial_url("http://interstitial");
14843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
14853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Show a first interstitial.
14863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage::InterstitialState state1 =
14873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TestInterstitialPage::UNDECIDED;
14883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool deleted1 = false;
14893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage* interstitial1 =
14903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new TestInterstitialPage(contents(), true, interstitial_url,
14913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &state1, &deleted1);
14923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPageStateGuard state_guard1(interstitial1);
14933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial1->Show();
14943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
14953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Show another interstitial on that same tab before the first one had time
14963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // to load.
14973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage::InterstitialState state2 =
14983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TestInterstitialPage::UNDECIDED;
14993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool deleted2 = false;
15003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage* interstitial2 =
15013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new TestInterstitialPage(contents(), true, interstitial_url,
15023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &state2, &deleted2);
15033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPageStateGuard state_guard2(interstitial2);
15043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial2->Show();
15053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The first interstitial should have been closed and deleted.
15073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(deleted1);
15083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
15093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The 2nd one should still be OK.
15113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_FALSE(deleted2);
15123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
15133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Make the interstitial navigation commit it should be showing.
15153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial2->TestDidNavigate(1, interstitial_url);
15163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(interstitial2, contents()->interstitial_page());
15173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
15183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test showing an interstitial and have its renderer crash.
1520c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, InterstitialCrasher) {
1521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show an interstitial.
1522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("http://interstitial");
1526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url, &state, &deleted);
1528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate a renderer crash before the interstitial is shown.
153121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  interstitial->TestRenderViewGone(
153221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should have been dismissed.
1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now try again but this time crash the intersitial after it was shown.
1538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial =
1539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, url, &state, &deleted);
1540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, url);
1542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate a renderer crash.
154321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  interstitial->TestRenderViewGone(
154421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should have been dismissed.
1546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that showing an interstitial as a result of a browser initiated
1551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// navigation while an interstitial is showing does not remove the pending
1552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// entry (see http://crbug.com/9791).
1553c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NewInterstitialDoesNotCancelPendingEntry) {
1554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kUrl[] = "http://www.badguys.com/";
1555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL kGURL(kUrl);
1556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start a navigation to a page
1558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->controller().LoadURL(kGURL, GURL(), PageTransition::TYPED);
1559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate that navigation triggering an interstitial.
1561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
1566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, kGURL);
1569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initiate a new navigation from the browser that also triggers an
1571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // interstitial.
1572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->controller().LoadURL(kGURL, GURL(), PageTransition::TYPED);
1573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state2 =
1574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted2 = false;
1576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial2 =
1577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
1578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard2(interstitial2);
1579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->Show();
1580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial2->TestDidNavigate(1, kGURL);
1581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we still have an entry.
1583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = contents()->controller().pending_entry();
1584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(entry);
1585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kUrl, entry->url().spec());
1586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And that the first interstitial is gone, but not the second.
1588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(deleted);
1589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::CANCELED, state);
1590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(deleted2);
1591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
1592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that Javascript messages are not shown while an interstitial is
1595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// showing.
1596c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabContentsTest, NoJSMessageOnInterstitials) {
1597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char kUrl[] = "http://www.badguys.com/";
1598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL kGURL(kUrl);
1599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start a navigation to a page
1601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->controller().LoadURL(kGURL, GURL(), PageTransition::TYPED);
1602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DidNavigate from the page
1603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ViewHostMsg_FrameNavigate_Params params;
1604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitNavigateParams(&params, 1, kGURL);
1605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->TestDidNavigate(rvh(), params);
1606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate showing an interstitial while the page is showing.
1608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage::InterstitialState state =
1609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestInterstitialPage::UNDECIDED;
1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool deleted = false;
1611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial =
1612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(contents(), true, kGURL, &state, &deleted);
1613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPageStateGuard state_guard(interstitial);
1614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->Show();
1615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial->TestDidNavigate(1, kGURL);
1616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // While the interstitial is showing, let's simulate the hidden page
1618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // attempting to show a JS message.
1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IPC::Message* dummy_message = new IPC::Message;
1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool did_suppress_message = false;
1621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents()->RunJavaScriptMessage(L"This is an informative message", L"OK",
162272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      kGURL, ui::MessageBoxFlags::kIsJavascriptAlert, dummy_message,
1623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &did_suppress_message);
1624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(did_suppress_message);
1625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
16263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Makes sure that if the source passed to CopyStateFromAndPrune has an
16283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// interstitial it isn't copied over to the destination.
16293345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(TabContentsTest, CopyStateFromAndPruneSourceInterstitial) {
16303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Navigate to a page.
16313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url1("http://www.google.com");
16323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rvh()->SendNavigate(1, url1);
16333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, controller().entry_count());
16343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Initiate a browser navigation that will trigger the interstitial
16363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  controller().LoadURL(GURL("http://www.evil.com"), GURL(),
16373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        PageTransition::TYPED);
16383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Show an interstitial.
16403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage::InterstitialState state =
16413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TestInterstitialPage::UNDECIDED;
16423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool deleted = false;
16433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url2("http://interstitial");
16443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage* interstitial =
16453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new TestInterstitialPage(contents(), true, url2, &state, &deleted);
16463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPageStateGuard state_guard(interstitial);
16473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial->Show();
16483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial->TestDidNavigate(1, url2);
16493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(interstitial->is_showing());
16503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(2, controller().entry_count());
16513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Create another NavigationController.
16533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url3("http://foo2");
16543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<TestTabContents> other_contents(CreateTestTabContents());
16553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NavigationController& other_controller = other_contents->controller();
16563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  other_contents->NavigateAndCommit(url3);
1657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  other_controller.CopyStateFromAndPrune(&controller(), false);
16583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The merged controller should only have two entries: url1 and url2.
16603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(2, other_controller.entry_count());
16613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
16623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->url());
16633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->url());
16643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And the merged controller shouldn't be showing an interstitial.
16663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(other_contents->showing_interstitial_page());
16673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
16683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Makes sure that CopyStateFromAndPrune does the right thing if the object
16703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// CopyStateFromAndPrune is invoked on is showing an interstitial.
16713345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(TabContentsTest, CopyStateFromAndPruneTargetInterstitial) {
16723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Navigate to a page.
16733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url1("http://www.google.com");
16743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  contents()->NavigateAndCommit(url1);
16753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Create another NavigationController.
16773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<TestTabContents> other_contents(CreateTestTabContents());
16783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NavigationController& other_controller = other_contents->controller();
16793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Navigate it to url2.
16813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url2("http://foo2");
16823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  other_contents->NavigateAndCommit(url2);
16833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Show an interstitial.
16853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage::InterstitialState state =
16863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TestInterstitialPage::UNDECIDED;
16873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool deleted = false;
16883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url3("http://interstitial");
16893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPage* interstitial =
16903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new TestInterstitialPage(other_contents.get(), true, url3, &state,
16913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &deleted);
16923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestInterstitialPageStateGuard state_guard(interstitial);
16933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial->Show();
16943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interstitial->TestDidNavigate(1, url3);
16953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(interstitial->is_showing());
16963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(2, other_controller.entry_count());
16973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  other_controller.CopyStateFromAndPrune(&controller(), false);
16993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The merged controller should only have two entries: url1 and url2.
17013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(2, other_controller.entry_count());
17023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
17033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->url());
17043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->url());
17053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // It should have a transient entry.
17073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(other_controller.GetTransientEntry());
17083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And the interstitial should be showing.
17103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(other_contents->showing_interstitial_page());
17113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And the interstitial should do a reload on don't proceed.
17133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(other_contents->interstitial_page()->reload_on_dont_proceed());
17143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1715dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1716dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass ConstrainedWindowCloseTest : public ConstrainedWindow {
1717dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen public:
1718dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  explicit ConstrainedWindowCloseTest(TabContents* tab_contents)
1719dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      : tab_contents_(tab_contents) {
1720dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1721dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1722dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void ShowConstrainedWindow() {}
1723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void FocusConstrainedWindow() {}
1724dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual ~ConstrainedWindowCloseTest() {}
1725dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1726dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void CloseConstrainedWindow() {
1727dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    tab_contents_->WillClose(this);
1728dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    close_count++;
1729dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1730dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1731dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int close_count;
1732dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContents* tab_contents_;
1733dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen};
1734dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1735dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(TabContentsTest, ConstrainedWindows) {
1736dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContents* tab_contents = CreateTestTabContents();
1737dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ConstrainedWindowCloseTest window(tab_contents);
1738dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  window.close_count = 0;
1739dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1740dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  const int kWindowCount = 4;
1741dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (int i = 0; i < kWindowCount; i++) {
1742dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    tab_contents->AddConstrainedDialog(&window);
1743dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1744dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(window.close_count, 0);
1745dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  delete tab_contents;
1746dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(window.close_count, kWindowCount);
1747dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1748