1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "chrome/browser/interstitial_page.h"
7 #include "chrome/browser/navigation_controller.h"
8 #include "chrome/browser/navigation_entry.h"
9 #include "chrome/browser/render_view_host.h"
10 #include "chrome/browser/render_widget_host_view.h"
11 #include "chrome/browser/web_contents.h"
12 #include "chrome/common/chrome_paths.h"
13 #include "chrome/common/ipc_channel.h"
14 #include "chrome/common/pref_service.h"
15 #include "chrome/common/render_messages.h"
16 #include "chrome/test/testing_profile.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 // Subclass the RenderViewHost's view so that we can call Show(), etc.,
20 // without having side-effects.
21 class TestRenderWidgetHostView
: public RenderWidgetHostView
{
23 TestRenderWidgetHostView() {}
24 void DidBecomeSelected() {}
26 void SetSize(const gfx::Size
& size
) {}
27 HWND
GetPluginHWND() { return NULL
; }
28 HANDLE
ModalDialogEvent() { return NULL
; }
29 void ForwardMouseEventToRenderer(UINT message
,
34 bool HasFocus() { return true; }
35 void AdvanceFocus(bool reverse
) {}
38 gfx::Rect
GetViewBounds() const { return gfx::Rect(); }
39 void UpdateCursor(const WebCursor
& cursor
) {}
40 void UpdateCursorIfOverSelf() {}
41 // Indicates if the page has finished loading.
42 virtual void SetIsLoading(bool is_loading
) {}
43 void IMEUpdateStatus(ViewHostMsg_ImeControl control
, int x
, int y
) {}
44 void DidPaintRect(const gfx::Rect
& rect
) {}
45 void DidScrollRect(const gfx::Rect
& rect
, int dx
, int dy
) {}
46 void RendererGone() {}
48 void PrepareToDestroy() {}
49 void SetTooltipText(const std::wstring
& tooltip_text
) {}
52 // Subclass RenderViewHost so that it does not create a process.
53 class TestRenderViewHost
: public RenderViewHost
{
56 SiteInstance
* instance
,
57 RenderViewHostDelegate
* delegate
,
59 HANDLE modal_dialog_event
)
60 : RenderViewHost(instance
, delegate
, routing_id
, modal_dialog_event
),
63 immediate_before_unload(true),
64 delete_counter_(NULL
) {
65 set_view(new TestRenderWidgetHostView());
67 ~TestRenderViewHost() {
68 // Track the delete if we've been asked to.
72 // Since this isn't a traditional view, we have to delete it.
76 // If set, *delete_counter is incremented when this object destructs.
77 void set_delete_counter(int* delete_counter
) {
78 delete_counter_
= delete_counter
;
81 bool CreateRenderView() {
86 bool IsRenderViewLive() const { return is_created
; }
88 bool IsNavigationSuspended() { return navigations_suspended_
; }
90 void NavigateToEntry(const NavigationEntry
& entry
, bool is_reload
) {
94 void LoadAlternateHTMLString(const std::string
& html_text
,
96 const GURL
& display_url
,
97 const std::string
& security_info
) {
101 // Support for onbeforeunload, onunload
102 void FirePageBeforeUnload() {
103 is_waiting_for_unload_ack_
= true;
104 if (immediate_before_unload
)
105 delegate()->ShouldClosePage(true);
107 void ClosePage(int new_render_process_host_id
, int new_request_id
) {
108 // Nothing to do here... This would cause a ClosePage_ACK to be sent to
109 // ResourceDispatcherHost, so we can simulate that manually.
111 void TestOnMsgShouldClose(bool proceed
) {
112 OnMsgShouldCloseACK(proceed
);
117 bool immediate_before_unload
;
118 int* delete_counter_
;
121 // Factory to create TestRenderViewHosts.
122 class TestRenderViewHostFactory
: public RenderViewHostFactory
{
124 static TestRenderViewHostFactory
* GetInstance() {
125 static TestRenderViewHostFactory instance
;
129 virtual RenderViewHost
* CreateRenderViewHost(
130 SiteInstance
* instance
,
131 RenderViewHostDelegate
* delegate
,
133 HANDLE modal_dialog_event
) {
134 return new TestRenderViewHost(
135 instance
, delegate
, routing_id
, modal_dialog_event
);
139 TestRenderViewHostFactory() {}
142 // Subclass the TestingProfile so that it can return certain services we need.
143 class WebContentsTestingProfile
: public TestingProfile
{
145 WebContentsTestingProfile() : TestingProfile() { }
147 virtual PrefService
* GetPrefs() {
149 std::wstring source_path
;
150 PathService::Get(chrome::DIR_TEST_DATA
, &source_path
);
151 file_util::AppendToPath(&source_path
, L
"profiles");
152 file_util::AppendToPath(&source_path
, L
"chrome_prefs");
153 file_util::AppendToPath(&source_path
, L
"Preferences");
155 prefs_
.reset(new PrefService(source_path
));
156 Profile::RegisterUserPrefs(prefs_
.get());
157 browser::RegisterAllPrefs(prefs_
.get(), prefs_
.get());
163 // Subclass WebContents to ensure it creates TestRenderViewHosts and does
164 // not do anything involving views.
165 class TestWebContents
: public WebContents
{
167 TestWebContents(Profile
* profile
, SiteInstance
* instance
)
168 : WebContents(profile
,
170 TestRenderViewHostFactory::GetInstance(),
173 transition_cross_site(false) {}
175 // Accessors for interesting fields
176 TestRenderViewHost
* rvh() {
177 return static_cast<TestRenderViewHost
*>(
178 render_manager_
.render_view_host_
);
180 TestRenderViewHost
* pending_rvh() {
181 return static_cast<TestRenderViewHost
*>(
182 render_manager_
.pending_render_view_host_
);
184 TestRenderViewHost
* interstitial_rvh() {
185 return static_cast<TestRenderViewHost
*>(
186 render_manager_
.interstitial_render_view_host_
);
188 TestRenderViewHost
* original_rvh() {
189 return static_cast<TestRenderViewHost
*>(
190 render_manager_
.original_render_view_host_
);
194 bool state_is_normal() const {
195 return render_manager_
.renderer_state_
== RenderViewHostManager::NORMAL
;
197 bool state_is_pending() const {
198 return render_manager_
.renderer_state_
== RenderViewHostManager::PENDING
;
200 bool state_is_entering_interstitial() const {
201 return render_manager_
.renderer_state_
==
202 RenderViewHostManager::ENTERING_INTERSTITIAL
;
204 bool state_is_interstitial() const {
205 return render_manager_
.renderer_state_
==
206 RenderViewHostManager::INTERSTITIAL
;
208 bool state_is_leaving_interstitial() const {
209 return render_manager_
.renderer_state_
==
210 RenderViewHostManager::LEAVING_INTERSTITIAL
;
213 // Ensure we create TestRenderViewHosts that don't spawn processes.
214 RenderViewHost
* CreateRenderViewHost(SiteInstance
* instance
,
215 RenderViewHostDelegate
* delegate
,
217 HANDLE modal_dialog_event
) {
218 return new TestRenderViewHost(
219 instance
, delegate
, routing_id
, modal_dialog_event
);
222 // Overrides WebContents::ShouldTransitionCrossSite so that we can test both
223 // alternatives without using command-line switches.
224 bool ShouldTransitionCrossSite() { return transition_cross_site
; }
226 // Promote DidNavigate to public.
227 void TestDidNavigate(TestRenderViewHost
* render_view_host
,
228 const ViewHostMsg_FrameNavigate_Params
& params
) {
229 DidNavigate(render_view_host
, params
);
230 render_view_host
->is_loading
= false;
233 // Promote GetWebkitPrefs to public.
234 WebPreferences
TestGetWebkitPrefs() {
235 return GetWebkitPrefs();
238 // Prevent interaction with views.
239 bool CreateRenderViewForRenderManager(RenderViewHost
* render_view_host
) {
240 // This will go to a TestRenderViewHost.
241 render_view_host
->CreateRenderView();
244 void UpdateRenderViewSizeForRenderManager() {}
246 // Set by individual tests.
247 bool transition_cross_site
;
250 class WebContentsTest
: public testing::Test
{
252 WebContentsTest() : contents(NULL
) {}
254 void InitNavigateParams(ViewHostMsg_FrameNavigate_Params
* params
,
257 params
->page_id
= pageID
;
259 params
->referrer
= GURL::EmptyGURL();
260 params
->transition
= PageTransition::TYPED
;
261 params
->redirects
= std::vector
<GURL
>();
262 params
->should_update_history
= false;
263 params
->searchable_form_url
= GURL::EmptyGURL();
264 params
->searchable_form_element_name
= std::wstring();
265 params
->searchable_form_encoding
= std::string();
266 params
->password_form
= PasswordForm();
267 params
->security_info
= std::string();
268 params
->gesture
= NavigationGestureUser
;
269 params
->is_post
= false;
272 // testing::Test methods:
274 virtual void SetUp() {
275 profile
.reset(new WebContentsTestingProfile());
277 // This will be deleted when the WebContents goes away
278 SiteInstance
* instance
= SiteInstance::CreateSiteInstance(profile
.get());
280 contents
= new TestWebContents(profile
.get(), instance
);
281 contents
->SetupController(profile
.get());
284 virtual void TearDown() {
285 // This will delete the contents.
286 contents
->CloseContents();
288 // Make sure that we flush any messages related to WebContents destruction
289 // before we destroy the profile.
290 MessageLoop::current()->RunAllPending();
293 scoped_ptr
<WebContentsTestingProfile
> profile
;
294 TestWebContents
* contents
;
297 MessageLoopForUI message_loop_
;
300 // Test to make sure that title updates get stripped of whitespace.
301 TEST_F(WebContentsTest
, UpdateTitle
) {
302 ViewHostMsg_FrameNavigate_Params params
;
303 InitNavigateParams(¶ms
, 0, GURL("about:blank"));
305 NavigationController::LoadCommittedDetails details
;
306 contents
->controller()->RendererDidNavigate(params
, false, &details
);
308 contents
->UpdateTitle(NULL
, 0, L
" Lots O' Whitespace\n");
309 EXPECT_EQ(std::wstring(L
"Lots O' Whitespace"), contents
->GetTitle());
312 // Test simple same-SiteInstance navigation.
313 TEST_F(WebContentsTest
, SimpleNavigation
) {
314 TestRenderViewHost
* orig_rvh
= contents
->rvh();
315 SiteInstance
* instance1
= contents
->GetSiteInstance();
316 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
317 EXPECT_TRUE(contents
->original_rvh() == NULL
);
318 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
319 EXPECT_FALSE(orig_rvh
->is_loading
);
322 const GURL
url("http://www.google.com");
323 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
324 EXPECT_TRUE(contents
->state_is_normal());
325 EXPECT_TRUE(orig_rvh
->is_loading
);
326 EXPECT_EQ(instance1
, orig_rvh
->site_instance());
327 // Controller's pending entry will have a NULL site instance until we assign
328 // it in DidNavigate.
330 contents
->controller()->GetActiveEntry()->site_instance() == NULL
);
332 // DidNavigate from the page
333 ViewHostMsg_FrameNavigate_Params params
;
334 InitNavigateParams(¶ms
, 1, url
);
335 contents
->TestDidNavigate(orig_rvh
, params
);
336 EXPECT_TRUE(contents
->state_is_normal());
337 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
338 EXPECT_EQ(instance1
, orig_rvh
->site_instance());
339 // Controller's entry should now have the SiteInstance, or else we won't be
340 // able to find it later.
342 contents
->controller()->GetActiveEntry()->site_instance());
345 // Test navigating to a page that shows an interstitial, then hiding it
346 // without proceeding.
347 TEST_F(WebContentsTest
, ShowInterstitialDontProceed
) {
348 TestRenderViewHost
* orig_rvh
= contents
->rvh();
349 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
350 EXPECT_TRUE(contents
->original_rvh() == NULL
);
351 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
352 EXPECT_FALSE(orig_rvh
->is_loading
);
355 const GURL
url("http://www.google.com");
356 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
357 EXPECT_TRUE(contents
->state_is_normal());
358 EXPECT_TRUE(orig_rvh
->is_loading
);
361 const GURL
interstitial_url("http://interstitial");
362 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
365 interstitial
->Show();
366 EXPECT_TRUE(contents
->state_is_entering_interstitial());
367 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
368 EXPECT_TRUE(orig_rvh
->is_loading
); // Still loading in the background
369 EXPECT_TRUE(interstitial_rvh
->is_loading
);
371 // DidNavigate from the interstitial
372 ViewHostMsg_FrameNavigate_Params params
;
373 InitNavigateParams(¶ms
, 1, url
);
374 contents
->TestDidNavigate(interstitial_rvh
, params
);
375 EXPECT_TRUE(contents
->state_is_interstitial());
376 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
377 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
378 EXPECT_FALSE(interstitial_rvh
->is_loading
);
380 // Hide interstitial (don't proceed)
381 contents
->HideInterstitialPage(false, false);
382 EXPECT_TRUE(contents
->state_is_normal());
383 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
384 EXPECT_TRUE(contents
->original_rvh() == NULL
);
385 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
388 // Test navigating to a page that shows an interstitial, then proceeding.
389 TEST_F(WebContentsTest
, ShowInterstitialProceed
) {
390 TestRenderViewHost
* orig_rvh
= contents
->rvh();
392 // The RenderViewHost's SiteInstance should not yet have a site.
393 EXPECT_EQ(GURL(), contents
->rvh()->site_instance()->site());
396 const GURL
url("http://www.google.com");
397 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
400 const GURL
interstitial_url("http://interstitial");
401 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
404 interstitial
->Show();
405 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
407 // DidNavigate from the interstitial
408 ViewHostMsg_FrameNavigate_Params params
;
409 InitNavigateParams(¶ms
, 1, url
);
410 contents
->TestDidNavigate(interstitial_rvh
, params
);
412 // Ensure this DidNavigate hasn't changed the SiteInstance's site.
413 // Prevents regression for bug 1163298.
414 EXPECT_EQ(GURL(), contents
->rvh()->site_instance()->site());
416 // Hide interstitial (proceed and wait)
417 contents
->HideInterstitialPage(true, true);
418 EXPECT_TRUE(contents
->state_is_leaving_interstitial());
419 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
420 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
422 // DidNavigate from the destination page
423 contents
->TestDidNavigate(orig_rvh
, params
);
424 EXPECT_TRUE(contents
->state_is_normal());
425 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
426 EXPECT_TRUE(contents
->original_rvh() == NULL
);
427 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
429 // The SiteInstance's site should now be updated.
430 EXPECT_EQ(GURL("http://google.com"),
431 contents
->rvh()->site_instance()->site());
433 // Since we weren't viewing a page before, we shouldn't be able to go back.
434 EXPECT_FALSE(contents
->controller()->CanGoBack());
437 // Test navigating to a page that shows an interstitial, then navigating away.
438 TEST_F(WebContentsTest
, ShowInterstitialThenNavigate
) {
439 TestRenderViewHost
* orig_rvh
= contents
->rvh();
442 const GURL
url("http://www.google.com");
443 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
446 const GURL
interstitial_url("http://interstitial");
447 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
450 interstitial
->Show();
451 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
453 // DidNavigate from the interstitial
454 ViewHostMsg_FrameNavigate_Params params
;
455 InitNavigateParams(¶ms
, 1, url
);
456 contents
->TestDidNavigate(interstitial_rvh
, params
);
458 // While interstitial showing, navigate to a new URL.
459 const GURL
url2("http://www.yahoo.com");
460 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
461 EXPECT_TRUE(contents
->state_is_leaving_interstitial());
462 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
463 EXPECT_TRUE(orig_rvh
->is_loading
);
464 EXPECT_FALSE(interstitial_rvh
->is_loading
);
466 // DidNavigate from the new URL. In the old process model, we'll still have
467 // the same RenderViewHost.
468 ViewHostMsg_FrameNavigate_Params params2
;
469 InitNavigateParams(¶ms2
, 2, url2
);
470 contents
->TestDidNavigate(orig_rvh
, params2
);
471 EXPECT_TRUE(contents
->state_is_normal());
472 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
473 EXPECT_FALSE(orig_rvh
->is_loading
);
476 // Ensures that an interstitial cannot be cancelled if a notification for a
477 // navigation from an IFrame from the previous page is received while the
478 // interstitial is being shown (bug #1182394).
479 TEST_F(WebContentsTest
, ShowInterstitialIFrameNavigate
) {
480 TestRenderViewHost
* orig_rvh
= contents
->rvh();
481 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
482 EXPECT_TRUE(contents
->original_rvh() == NULL
);
483 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
484 EXPECT_FALSE(orig_rvh
->is_loading
);
487 const GURL
url("http://www.google.com");
488 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
489 EXPECT_TRUE(contents
->state_is_normal());
490 EXPECT_TRUE(orig_rvh
->is_loading
);
491 ViewHostMsg_FrameNavigate_Params params1
;
492 InitNavigateParams(¶ms1
, 1, url
);
493 contents
->TestDidNavigate(orig_rvh
, params1
);
495 // Show interstitial (in real world would probably be triggered by a resource
497 const GURL
interstitial_url("http://interstitial");
498 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
501 interstitial
->Show();
502 EXPECT_TRUE(contents
->state_is_entering_interstitial());
503 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
504 EXPECT_TRUE(interstitial_rvh
->is_loading
);
506 // DidNavigate from an IFrame in the initial page.
507 ViewHostMsg_FrameNavigate_Params params2
;
508 InitNavigateParams(¶ms2
, 1, GURL("http://www.iframe.com"));
509 params2
.transition
= PageTransition::AUTO_SUBFRAME
;
510 contents
->TestDidNavigate(orig_rvh
, params2
);
512 // Now we get the DidNavigate from the interstitial.
513 ViewHostMsg_FrameNavigate_Params params3
;
514 InitNavigateParams(¶ms3
, 1, url
);
515 contents
->TestDidNavigate(interstitial_rvh
, params3
);
516 EXPECT_TRUE(contents
->state_is_interstitial());
517 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
518 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
519 EXPECT_FALSE(interstitial_rvh
->is_loading
);
522 // Test navigating to an interstitial page from a normal page. Also test
523 // visiting the interstitial-inducing URL twice (bug 1079784), and test
524 // that going back shows the first page and not the interstitial.
525 TEST_F(WebContentsTest
, VisitInterstitialURLTwice
) {
526 TestRenderViewHost
* orig_rvh
= contents
->rvh();
529 const GURL
url("http://www.google.com");
530 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
531 ViewHostMsg_FrameNavigate_Params params1
;
532 InitNavigateParams(¶ms1
, 1, url
);
533 contents
->TestDidNavigate(orig_rvh
, params1
);
535 // Now navigate to an interstitial-inducing URL
536 const GURL
url2("https://www.google.com");
537 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
538 const GURL
interstitial_url("http://interstitial");
539 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
542 interstitial
->Show();
543 EXPECT_TRUE(contents
->state_is_entering_interstitial());
544 int interstitial_delete_counter
= 0;
545 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
546 interstitial_rvh
->set_delete_counter(&interstitial_delete_counter
);
548 // DidNavigate from the interstitial
549 ViewHostMsg_FrameNavigate_Params params2
;
550 InitNavigateParams(¶ms2
, 2, url2
);
551 contents
->TestDidNavigate(interstitial_rvh
, params2
);
552 EXPECT_TRUE(contents
->state_is_interstitial());
553 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
555 // While interstitial showing, navigate to the same URL.
556 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
557 EXPECT_TRUE(contents
->state_is_leaving_interstitial());
558 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
560 // Interstitial shown a second time in a different RenderViewHost.
561 interstitial
= new InterstitialPage(contents
, true, interstitial_url
);
562 interstitial
->Show();
563 EXPECT_TRUE(contents
->state_is_entering_interstitial());
564 // We expect the original interstitial has been deleted.
565 EXPECT_EQ(interstitial_delete_counter
, 1);
566 TestRenderViewHost
* interstitial_rvh2
= contents
->interstitial_rvh();
567 interstitial_rvh2
->set_delete_counter(&interstitial_delete_counter
);
569 // DidNavigate from the interstitial.
570 ViewHostMsg_FrameNavigate_Params params3
;
571 InitNavigateParams(¶ms3
, 3, url2
);
572 contents
->TestDidNavigate(interstitial_rvh2
, params3
);
573 EXPECT_TRUE(contents
->state_is_interstitial());
574 EXPECT_EQ(interstitial_rvh2
, contents
->render_view_host());
576 // Proceed. In the old process model, we'll still have the same
578 contents
->HideInterstitialPage(true, true);
579 EXPECT_TRUE(contents
->state_is_leaving_interstitial());
580 ViewHostMsg_FrameNavigate_Params params4
;
581 InitNavigateParams(¶ms4
, 3, url2
);
582 contents
->TestDidNavigate(orig_rvh
, params4
);
583 EXPECT_TRUE(contents
->state_is_normal());
584 // We expect the second interstitial has been deleted.
585 EXPECT_EQ(interstitial_delete_counter
, 2);
587 // Now go back. Should take us back to the original page.
588 contents
->controller()->GoBack();
589 EXPECT_TRUE(contents
->state_is_normal());
591 // DidNavigate from going back.
592 contents
->TestDidNavigate(orig_rvh
, params1
);
593 EXPECT_TRUE(contents
->state_is_normal());
594 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
595 EXPECT_TRUE(contents
->original_rvh() == NULL
);
596 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
599 // Test that navigating across a site boundary creates a new RenderViewHost
600 // with a new SiteInstance. Going back should do the same.
601 TEST_F(WebContentsTest
, CrossSiteBoundaries
) {
602 contents
->transition_cross_site
= true;
603 TestRenderViewHost
* orig_rvh
= contents
->rvh();
604 int orig_rvh_delete_count
= 0;
605 orig_rvh
->set_delete_counter(&orig_rvh_delete_count
);
606 SiteInstance
* instance1
= contents
->GetSiteInstance();
608 // Navigate to URL. First URL should use first RenderViewHost.
609 const GURL
url("http://www.google.com");
610 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
611 ViewHostMsg_FrameNavigate_Params params1
;
612 InitNavigateParams(¶ms1
, 1, url
);
613 contents
->TestDidNavigate(orig_rvh
, params1
);
615 EXPECT_TRUE(contents
->state_is_normal());
616 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
617 EXPECT_TRUE(contents
->original_rvh() == NULL
);
618 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
620 // Navigate to new site
621 const GURL
url2("http://www.yahoo.com");
622 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
623 EXPECT_TRUE(contents
->state_is_pending());
624 TestRenderViewHost
* pending_rvh
= contents
->pending_rvh();
625 int pending_rvh_delete_count
= 0;
626 pending_rvh
->set_delete_counter(&pending_rvh_delete_count
);
628 // DidNavigate from the pending page
629 ViewHostMsg_FrameNavigate_Params params2
;
630 InitNavigateParams(¶ms2
, 1, url2
);
631 contents
->TestDidNavigate(pending_rvh
, params2
);
632 SiteInstance
* instance2
= contents
->GetSiteInstance();
634 EXPECT_TRUE(contents
->state_is_normal());
635 EXPECT_EQ(pending_rvh
, contents
->render_view_host());
636 EXPECT_NE(instance1
, instance2
);
637 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
638 EXPECT_TRUE(contents
->original_rvh() == NULL
);
639 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
640 EXPECT_EQ(orig_rvh_delete_count
, 1);
642 // Going back should switch SiteInstances again. The first SiteInstance is
643 // stored in the NavigationEntry, so it should be the same as at the start.
644 contents
->controller()->GoBack();
645 TestRenderViewHost
* goback_rvh
= contents
->pending_rvh();
646 EXPECT_TRUE(contents
->state_is_pending());
648 // DidNavigate from the back action
649 contents
->TestDidNavigate(goback_rvh
, params1
);
650 EXPECT_TRUE(contents
->state_is_normal());
651 EXPECT_EQ(goback_rvh
, contents
->render_view_host());
652 EXPECT_EQ(pending_rvh_delete_count
, 1);
653 EXPECT_EQ(instance1
, contents
->GetSiteInstance());
656 // Test that navigating across a site boundary after a crash creates a new
657 // RVH without requiring a cross-site transition (i.e., PENDING state).
658 TEST_F(WebContentsTest
, CrossSiteBoundariesAfterCrash
) {
659 contents
->transition_cross_site
= true;
660 TestRenderViewHost
* orig_rvh
= contents
->rvh();
661 int orig_rvh_delete_count
= 0;
662 orig_rvh
->set_delete_counter(&orig_rvh_delete_count
);
663 SiteInstance
* instance1
= contents
->GetSiteInstance();
665 // Navigate to URL. First URL should use first RenderViewHost.
666 const GURL
url("http://www.google.com");
667 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
668 ViewHostMsg_FrameNavigate_Params params1
;
669 InitNavigateParams(¶ms1
, 1, url
);
670 contents
->TestDidNavigate(orig_rvh
, params1
);
672 EXPECT_TRUE(contents
->state_is_normal());
673 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
674 EXPECT_TRUE(contents
->original_rvh() == NULL
);
675 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
677 // Crash the renderer.
678 orig_rvh
->is_created
= false;
680 // Navigate to new site. We should not go into PENDING.
681 const GURL
url2("http://www.yahoo.com");
682 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
683 TestRenderViewHost
* new_rvh
= contents
->rvh();
684 EXPECT_TRUE(contents
->state_is_normal());
685 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
686 EXPECT_TRUE(contents
->original_rvh() == NULL
);
687 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
688 EXPECT_NE(orig_rvh
, new_rvh
);
689 EXPECT_EQ(orig_rvh_delete_count
, 1);
691 // DidNavigate from the new page
692 ViewHostMsg_FrameNavigate_Params params2
;
693 InitNavigateParams(¶ms2
, 1, url2
);
694 contents
->TestDidNavigate(new_rvh
, params2
);
695 SiteInstance
* instance2
= contents
->GetSiteInstance();
697 EXPECT_TRUE(contents
->state_is_normal());
698 EXPECT_EQ(new_rvh
, contents
->render_view_host());
699 EXPECT_NE(instance1
, instance2
);
700 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
701 EXPECT_TRUE(contents
->original_rvh() == NULL
);
702 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
705 // Test state transitions when showing an interstitial in the new process
706 // model, and then choosing DontProceed.
707 TEST_F(WebContentsTest
, CrossSiteInterstitialDontProceed
) {
708 contents
->transition_cross_site
= true;
709 TestRenderViewHost
* orig_rvh
= contents
->rvh();
710 SiteInstance
* instance1
= contents
->GetSiteInstance();
712 // Navigate to URL. First URL should use first RenderViewHost.
713 const GURL
url("http://www.google.com");
714 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
715 ViewHostMsg_FrameNavigate_Params params1
;
716 InitNavigateParams(¶ms1
, 1, url
);
717 contents
->TestDidNavigate(orig_rvh
, params1
);
719 EXPECT_TRUE(contents
->state_is_normal());
720 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
722 // Navigate to new site
723 const GURL
url2("https://www.google.com");
724 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
725 EXPECT_TRUE(contents
->state_is_pending());
726 TestRenderViewHost
* pending_rvh
= contents
->pending_rvh();
728 // Show an interstitial
729 const GURL
interstitial_url("http://interstitial");
730 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
733 interstitial
->Show();
734 EXPECT_TRUE(contents
->state_is_entering_interstitial());
735 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
736 EXPECT_EQ(pending_rvh
, contents
->pending_rvh());
737 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
739 // DidNavigate from the interstitial
740 ViewHostMsg_FrameNavigate_Params params2
;
741 InitNavigateParams(¶ms2
, 2, url2
);
742 contents
->TestDidNavigate(interstitial_rvh
, params2
);
743 EXPECT_TRUE(contents
->state_is_interstitial());
744 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
745 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
746 EXPECT_EQ(pending_rvh
, contents
->pending_rvh());
747 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
749 // Hide interstitial (don't proceed)
750 contents
->HideInterstitialPage(false, false);
751 EXPECT_TRUE(contents
->state_is_normal());
752 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
753 EXPECT_TRUE(contents
->original_rvh() == NULL
);
754 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
755 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
758 // Test state transitions when showing an interstitial in the new process
759 // model, and then choosing Proceed.
760 TEST_F(WebContentsTest
, CrossSiteInterstitialProceed
) {
761 contents
->transition_cross_site
= true;
762 int orig_rvh_delete_count
= 0;
763 TestRenderViewHost
* orig_rvh
= contents
->rvh();
764 orig_rvh
->set_delete_counter(&orig_rvh_delete_count
);
765 SiteInstance
* instance1
= contents
->GetSiteInstance();
767 // Navigate to URL. First URL should use first RenderViewHost.
768 const GURL
url("http://www.google.com");
769 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
770 ViewHostMsg_FrameNavigate_Params params1
;
771 InitNavigateParams(¶ms1
, 1, url
);
772 contents
->TestDidNavigate(orig_rvh
, params1
);
774 // Navigate to new site
775 const GURL
url2("https://www.google.com");
776 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
777 TestRenderViewHost
* pending_rvh
= contents
->pending_rvh();
778 int pending_rvh_delete_count
= 0;
779 pending_rvh
->set_delete_counter(&pending_rvh_delete_count
);
781 // Show an interstitial
782 const GURL
interstitial_url("http://interstitial");
783 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
786 interstitial
->Show();
787 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
789 // DidNavigate from the interstitial
790 ViewHostMsg_FrameNavigate_Params params2
;
791 InitNavigateParams(¶ms2
, 1, url2
);
792 contents
->TestDidNavigate(interstitial_rvh
, params2
);
793 EXPECT_TRUE(contents
->state_is_interstitial());
794 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
795 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
796 EXPECT_EQ(pending_rvh
, contents
->pending_rvh());
797 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
799 // Hide interstitial (proceed and wait)
800 contents
->HideInterstitialPage(true, true);
801 EXPECT_TRUE(contents
->state_is_leaving_interstitial());
802 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
803 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
804 EXPECT_EQ(pending_rvh
, contents
->pending_rvh());
805 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
807 // DidNavigate from the destination page should transition to new renderer
808 ViewHostMsg_FrameNavigate_Params params3
;
809 InitNavigateParams(¶ms3
, 2, url2
);
810 contents
->TestDidNavigate(pending_rvh
, params3
);
811 SiteInstance
* instance2
= contents
->GetSiteInstance();
812 EXPECT_TRUE(contents
->state_is_normal());
813 EXPECT_EQ(pending_rvh
, contents
->render_view_host());
814 EXPECT_TRUE(contents
->original_rvh() == NULL
);
815 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
816 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
817 EXPECT_NE(instance1
, instance2
);
818 EXPECT_EQ(orig_rvh_delete_count
, 1); // The original should be gone.
820 // Since we were viewing a page before, we should be able to go back.
821 EXPECT_TRUE(contents
->controller()->CanGoBack());
823 // Going back should switch SiteInstances again. The first SiteInstance is
824 // stored in the NavigationEntry, so it should be the same as at the start.
825 contents
->controller()->GoBack();
826 TestRenderViewHost
* goback_rvh
= contents
->pending_rvh();
827 EXPECT_TRUE(contents
->state_is_pending());
829 // DidNavigate from the back action
830 contents
->TestDidNavigate(goback_rvh
, params1
);
831 EXPECT_TRUE(contents
->state_is_normal());
832 EXPECT_EQ(goback_rvh
, contents
->render_view_host());
833 EXPECT_EQ(instance1
, contents
->GetSiteInstance());
834 EXPECT_EQ(pending_rvh_delete_count
, 1); // The second page's rvh should die.
837 // Tests that we can transition away from an interstitial page.
838 TEST_F(WebContentsTest
, CrossSiteInterstitialThenNavigate
) {
839 contents
->transition_cross_site
= true;
840 int orig_rvh_delete_count
= 0;
841 TestRenderViewHost
* orig_rvh
= contents
->rvh();
842 orig_rvh
->set_delete_counter(&orig_rvh_delete_count
);
844 // Navigate to URL. First URL should use first RenderViewHost.
845 const GURL
url("http://www.google.com");
846 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
847 ViewHostMsg_FrameNavigate_Params params1
;
848 InitNavigateParams(¶ms1
, 1, url
);
849 contents
->TestDidNavigate(orig_rvh
, params1
);
851 // Show an interstitial
852 const GURL
interstitial_url("http://interstitial");
853 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
856 interstitial
->Show();
857 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
859 // DidNavigate from the interstitial
860 ViewHostMsg_FrameNavigate_Params params2
;
861 InitNavigateParams(¶ms2
, 1, url
);
862 contents
->TestDidNavigate(interstitial_rvh
, params2
);
863 EXPECT_TRUE(contents
->state_is_interstitial());
864 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
865 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
866 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
868 // Navigate to a new page.
869 const GURL
url2("http://www.yahoo.com");
870 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
872 TestRenderViewHost
* new_rvh
= contents
->pending_rvh();
873 ASSERT_TRUE(new_rvh
!= NULL
);
874 // Make sure the RVH is not suspended (bug #1236441).
875 EXPECT_FALSE(new_rvh
->IsNavigationSuspended());
876 EXPECT_TRUE(contents
->state_is_leaving_interstitial());
877 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
879 // DidNavigate from the new page
880 ViewHostMsg_FrameNavigate_Params params3
;
881 InitNavigateParams(¶ms3
, 1, url2
);
882 contents
->TestDidNavigate(new_rvh
, params3
);
883 EXPECT_TRUE(contents
->state_is_normal());
884 EXPECT_EQ(new_rvh
, contents
->render_view_host());
885 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
886 EXPECT_EQ(orig_rvh_delete_count
, 1);
889 // Tests that we can transition away from an interstitial page even if the
890 // interstitial renderer has crashed.
891 TEST_F(WebContentsTest
, CrossSiteInterstitialCrashThenNavigate
) {
892 contents
->transition_cross_site
= true;
893 int orig_rvh_delete_count
= 0;
894 TestRenderViewHost
* orig_rvh
= contents
->rvh();
895 orig_rvh
->set_delete_counter(&orig_rvh_delete_count
);
897 // Navigate to URL. First URL should use first RenderViewHost.
898 const GURL
url("http://www.google.com");
899 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
900 ViewHostMsg_FrameNavigate_Params params1
;
901 InitNavigateParams(¶ms1
, 1, url
);
902 contents
->TestDidNavigate(orig_rvh
, params1
);
904 // Navigate to new site
905 const GURL
url2("https://www.google.com");
906 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
907 TestRenderViewHost
* pending_rvh
= contents
->pending_rvh();
908 int pending_rvh_delete_count
= 0;
909 pending_rvh
->set_delete_counter(&pending_rvh_delete_count
);
911 // Show an interstitial
912 const GURL
interstitial_url("http://interstitial");
913 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
916 interstitial
->Show();
917 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
919 // DidNavigate from the interstitial
920 ViewHostMsg_FrameNavigate_Params params2
;
921 InitNavigateParams(¶ms2
, 1, url2
);
922 contents
->TestDidNavigate(interstitial_rvh
, params2
);
923 EXPECT_TRUE(contents
->state_is_interstitial());
924 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
925 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
926 EXPECT_EQ(pending_rvh
, contents
->pending_rvh());
927 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
929 // Crash the interstitial RVH
930 // (by making IsRenderViewLive() == false)
931 interstitial_rvh
->is_created
= false;
933 // Navigate to a new page. Since interstitial RVH is dead, we should clean
934 // it up and go to a new PENDING state, showing the orig_rvh.
935 const GURL
url3("http://www.yahoo.com");
936 contents
->controller()->LoadURL(url3
, PageTransition::TYPED
);
937 TestRenderViewHost
* new_rvh
= contents
->pending_rvh();
938 ASSERT_TRUE(new_rvh
!= NULL
);
939 EXPECT_TRUE(contents
->state_is_pending());
940 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
941 EXPECT_EQ(pending_rvh_delete_count
, 1);
942 EXPECT_NE(interstitial_rvh
, new_rvh
);
943 EXPECT_TRUE(contents
->original_rvh() == NULL
);
944 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
946 // DidNavigate from the new page
947 ViewHostMsg_FrameNavigate_Params params3
;
948 InitNavigateParams(¶ms3
, 1, url3
);
949 contents
->TestDidNavigate(new_rvh
, params3
);
950 EXPECT_TRUE(contents
->state_is_normal());
951 EXPECT_EQ(new_rvh
, contents
->render_view_host());
952 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
953 EXPECT_EQ(orig_rvh_delete_count
, 1);
956 // Tests that we can transition away from an interstitial page even if both the
957 // original and interstitial renderers have crashed.
958 TEST_F(WebContentsTest
, CrossSiteInterstitialCrashesThenNavigate
) {
959 contents
->transition_cross_site
= true;
960 int orig_rvh_delete_count
= 0;
961 TestRenderViewHost
* orig_rvh
= contents
->rvh();
962 orig_rvh
->set_delete_counter(&orig_rvh_delete_count
);
964 // Navigate to URL. First URL should use first RenderViewHost.
965 const GURL
url("http://www.google.com");
966 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
967 ViewHostMsg_FrameNavigate_Params params1
;
968 InitNavigateParams(¶ms1
, 1, url
);
969 contents
->TestDidNavigate(orig_rvh
, params1
);
971 // Navigate to new site
972 const GURL
url2("https://www.google.com");
973 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
974 TestRenderViewHost
* pending_rvh
= contents
->pending_rvh();
975 int pending_rvh_delete_count
= 0;
976 pending_rvh
->set_delete_counter(&pending_rvh_delete_count
);
978 // Show an interstitial
979 const GURL
interstitial_url("http://interstitial");
980 InterstitialPage
* interstitial
= new InterstitialPage(contents
,
983 interstitial
->Show();
984 TestRenderViewHost
* interstitial_rvh
= contents
->interstitial_rvh();
986 // DidNavigate from the interstitial
987 ViewHostMsg_FrameNavigate_Params params2
;
988 InitNavigateParams(¶ms2
, 1, url2
);
989 contents
->TestDidNavigate(interstitial_rvh
, params2
);
990 EXPECT_TRUE(contents
->state_is_interstitial());
991 EXPECT_EQ(interstitial_rvh
, contents
->render_view_host());
992 EXPECT_EQ(orig_rvh
, contents
->original_rvh());
993 EXPECT_EQ(pending_rvh
, contents
->pending_rvh());
994 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
996 // Crash both the original and interstitial RVHs
997 // (by making IsRenderViewLive() == false)
998 orig_rvh
->is_created
= false;
999 interstitial_rvh
->is_created
= false;
1001 // Navigate to a new page. Since both the interstitial and original RVHs are
1002 // dead, we should create a new RVH, jump back to NORMAL, and navigate.
1003 const GURL
url3("http://www.yahoo.com");
1004 contents
->controller()->LoadURL(url3
, PageTransition::TYPED
);
1005 TestRenderViewHost
* new_rvh
= contents
->rvh();
1006 ASSERT_TRUE(new_rvh
!= NULL
);
1007 EXPECT_TRUE(contents
->state_is_normal());
1008 EXPECT_EQ(orig_rvh_delete_count
, 1);
1009 EXPECT_EQ(pending_rvh_delete_count
, 1);
1010 EXPECT_NE(interstitial_rvh
, new_rvh
);
1011 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
1012 EXPECT_TRUE(contents
->original_rvh() == NULL
);
1013 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
1015 // DidNavigate from the new page
1016 ViewHostMsg_FrameNavigate_Params params3
;
1017 InitNavigateParams(¶ms3
, 1, url3
);
1018 contents
->TestDidNavigate(new_rvh
, params3
);
1019 EXPECT_TRUE(contents
->state_is_normal());
1020 EXPECT_EQ(new_rvh
, contents
->render_view_host());
1023 // Test that opening a new tab in the same SiteInstance and then navigating
1024 // both tabs to a new site will place both tabs in a single SiteInstance.
1025 TEST_F(WebContentsTest
, NavigateTwoTabsCrossSite
) {
1026 contents
->transition_cross_site
= true;
1027 TestRenderViewHost
* orig_rvh
= contents
->rvh();
1028 SiteInstance
* instance1
= contents
->GetSiteInstance();
1030 // Navigate to URL. First URL should use first RenderViewHost.
1031 const GURL
url("http://www.google.com");
1032 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
1033 ViewHostMsg_FrameNavigate_Params params1
;
1034 InitNavigateParams(¶ms1
, 1, url
);
1035 contents
->TestDidNavigate(orig_rvh
, params1
);
1037 // Open a new tab with the same SiteInstance, navigated to the same site.
1038 TestWebContents
* contents2
= new TestWebContents(profile
.get(), instance1
);
1039 params1
.page_id
= 2; // Need this since the site instance is the same (which
1040 // is the scope of page IDs) and we want to consider
1042 contents2
->transition_cross_site
= true;
1043 contents2
->SetupController(profile
.get());
1044 contents2
->controller()->LoadURL(url
, PageTransition::TYPED
);
1045 contents2
->TestDidNavigate(contents2
->rvh(), params1
);
1047 // Navigate first tab to a new site
1048 const GURL
url2a("http://www.yahoo.com");
1049 contents
->controller()->LoadURL(url2a
, PageTransition::TYPED
);
1050 TestRenderViewHost
* pending_rvh_a
= contents
->pending_rvh();
1051 ViewHostMsg_FrameNavigate_Params params2a
;
1052 InitNavigateParams(¶ms2a
, 1, url2a
);
1053 contents
->TestDidNavigate(pending_rvh_a
, params2a
);
1054 SiteInstance
* instance2a
= contents
->GetSiteInstance();
1055 EXPECT_NE(instance1
, instance2a
);
1057 // Navigate second tab to the same site as the first tab
1058 const GURL
url2b("http://mail.yahoo.com");
1059 contents2
->controller()->LoadURL(url2b
, PageTransition::TYPED
);
1060 TestRenderViewHost
* pending_rvh_b
= contents2
->pending_rvh();
1061 EXPECT_TRUE(pending_rvh_b
!= NULL
);
1062 EXPECT_TRUE(contents2
->state_is_pending());
1064 // NOTE(creis): We used to be in danger of showing a sad tab page here if the
1065 // second tab hadn't navigated somewhere first (bug 1145430). That case is
1066 // now covered by the CrossSiteBoundariesAfterCrash test.
1068 ViewHostMsg_FrameNavigate_Params params2b
;
1069 InitNavigateParams(¶ms2b
, 2, url2b
);
1070 contents2
->TestDidNavigate(pending_rvh_b
, params2b
);
1071 SiteInstance
* instance2b
= contents2
->GetSiteInstance();
1072 EXPECT_NE(instance1
, instance2b
);
1074 // Both tabs should now be in the same SiteInstance.
1075 EXPECT_EQ(instance2a
, instance2b
);
1077 contents2
->CloseContents();
1080 // Tests that WebContents uses the current URL, not the SiteInstance's site, to
1081 // determine whether a navigation is cross-site.
1082 TEST_F(WebContentsTest
, CrossSiteComparesAgainstCurrentPage
) {
1083 contents
->transition_cross_site
= true;
1084 TestRenderViewHost
* orig_rvh
= contents
->rvh();
1085 SiteInstance
* instance1
= contents
->GetSiteInstance();
1088 const GURL
url("http://www.google.com");
1089 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
1090 ViewHostMsg_FrameNavigate_Params params1
;
1091 InitNavigateParams(¶ms1
, 1, url
);
1092 contents
->TestDidNavigate(orig_rvh
, params1
);
1094 // Open a related tab to a second site.
1095 TestWebContents
* contents2
= new TestWebContents(profile
.get(), instance1
);
1096 contents2
->transition_cross_site
= true;
1097 contents2
->SetupController(profile
.get());
1098 const GURL
url2("http://www.yahoo.com");
1099 contents2
->controller()->LoadURL(url2
, PageTransition::TYPED
);
1100 // The first RVH in contents2 isn't live yet, so we shortcut the PENDING
1101 // state and go straight to NORMAL.
1102 TestRenderViewHost
* rvh2
= contents2
->rvh();
1103 EXPECT_TRUE(contents2
->state_is_normal());
1104 ViewHostMsg_FrameNavigate_Params params2
;
1105 InitNavigateParams(¶ms2
, 2, url2
);
1106 contents2
->TestDidNavigate(rvh2
, params2
);
1107 SiteInstance
* instance2
= contents2
->GetSiteInstance();
1108 EXPECT_NE(instance1
, instance2
);
1109 EXPECT_TRUE(contents2
->state_is_normal());
1111 // Simulate a link click in first tab to second site. Doesn't switch
1112 // SiteInstances, because we don't intercept WebKit navigations.
1113 ViewHostMsg_FrameNavigate_Params params3
;
1114 InitNavigateParams(¶ms3
, 2, url2
);
1115 contents
->TestDidNavigate(orig_rvh
, params3
);
1116 SiteInstance
* instance3
= contents
->GetSiteInstance();
1117 EXPECT_EQ(instance1
, instance3
);
1118 EXPECT_TRUE(contents
->state_is_normal());
1120 // Navigate to the new site. Doesn't switch SiteInstancees, because we
1121 // compare against the current URL, not the SiteInstance's site.
1122 const GURL
url3("http://mail.yahoo.com");
1123 contents
->controller()->LoadURL(url3
, PageTransition::TYPED
);
1124 EXPECT_TRUE(contents
->state_is_normal());
1125 ViewHostMsg_FrameNavigate_Params params4
;
1126 InitNavigateParams(¶ms4
, 3, url3
);
1127 contents
->TestDidNavigate(orig_rvh
, params4
);
1128 SiteInstance
* instance4
= contents
->GetSiteInstance();
1129 EXPECT_EQ(instance1
, instance4
);
1131 contents2
->CloseContents();
1134 // Test that the onbeforeunload and onunload handlers run when navigating
1135 // across site boundaries.
1136 TEST_F(WebContentsTest
, CrossSiteUnloadHandlers
) {
1137 contents
->transition_cross_site
= true;
1138 TestRenderViewHost
* orig_rvh
= contents
->rvh();
1139 SiteInstance
* instance1
= contents
->GetSiteInstance();
1141 // Navigate to URL. First URL should use first RenderViewHost.
1142 const GURL
url("http://www.google.com");
1143 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
1144 ViewHostMsg_FrameNavigate_Params params1
;
1145 InitNavigateParams(¶ms1
, 1, url
);
1146 contents
->TestDidNavigate(orig_rvh
, params1
);
1147 EXPECT_TRUE(contents
->state_is_normal());
1148 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
1150 // Navigate to new site, but simulate an onbeforeunload denial.
1151 const GURL
url2("http://www.yahoo.com");
1152 orig_rvh
->immediate_before_unload
= false;
1153 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
1154 orig_rvh
->TestOnMsgShouldClose(false);
1155 EXPECT_TRUE(contents
->state_is_normal());
1156 EXPECT_EQ(orig_rvh
, contents
->render_view_host());
1158 // Navigate again, but simulate an onbeforeunload approval.
1159 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
1160 orig_rvh
->TestOnMsgShouldClose(true);
1161 EXPECT_TRUE(contents
->state_is_pending());
1162 TestRenderViewHost
* pending_rvh
= contents
->pending_rvh();
1164 // We won't hear DidNavigate until the onunload handler has finished running.
1165 // (No way to simulate that here, but it involves a call from RDH to
1166 // WebContents::OnCrossSiteResponse.)
1168 // DidNavigate from the pending page
1169 ViewHostMsg_FrameNavigate_Params params2
;
1170 InitNavigateParams(¶ms2
, 1, url2
);
1171 contents
->TestDidNavigate(pending_rvh
, params2
);
1172 SiteInstance
* instance2
= contents
->GetSiteInstance();
1173 EXPECT_TRUE(contents
->state_is_normal());
1174 EXPECT_EQ(pending_rvh
, contents
->render_view_host());
1175 EXPECT_NE(instance1
, instance2
);
1176 EXPECT_TRUE(contents
->pending_rvh() == NULL
);
1177 EXPECT_TRUE(contents
->original_rvh() == NULL
);
1178 EXPECT_TRUE(contents
->interstitial_rvh() == NULL
);
1181 // Test that NavigationEntries have the correct content state after going
1182 // forward and back. Prevents regression for bug 1116137.
1183 TEST_F(WebContentsTest
, NavigationEntryContentState
) {
1184 TestRenderViewHost
* orig_rvh
= contents
->rvh();
1186 // Navigate to URL. There should be no committed entry yet.
1187 const GURL
url("http://www.google.com");
1188 contents
->controller()->LoadURL(url
, PageTransition::TYPED
);
1189 NavigationEntry
* entry
= contents
->controller()->GetLastCommittedEntry();
1190 EXPECT_TRUE(entry
== NULL
);
1192 // Committed entry should have content state after DidNavigate.
1193 ViewHostMsg_FrameNavigate_Params params1
;
1194 InitNavigateParams(¶ms1
, 1, url
);
1195 contents
->TestDidNavigate(orig_rvh
, params1
);
1196 entry
= contents
->controller()->GetLastCommittedEntry();
1197 EXPECT_FALSE(entry
->content_state().empty());
1199 // Navigate to same site.
1200 const GURL
url2("http://images.google.com");
1201 contents
->controller()->LoadURL(url2
, PageTransition::TYPED
);
1202 entry
= contents
->controller()->GetLastCommittedEntry();
1203 EXPECT_FALSE(entry
->content_state().empty());
1205 // Committed entry should have content state after DidNavigate.
1206 ViewHostMsg_FrameNavigate_Params params2
;
1207 InitNavigateParams(¶ms2
, 2, url2
);
1208 contents
->TestDidNavigate(orig_rvh
, params2
);
1209 entry
= contents
->controller()->GetLastCommittedEntry();
1210 EXPECT_FALSE(entry
->content_state().empty());
1212 // Now go back. Committed entry should still have content state.
1213 contents
->controller()->GoBack();
1214 contents
->TestDidNavigate(orig_rvh
, params1
);
1215 entry
= contents
->controller()->GetLastCommittedEntry();
1216 EXPECT_FALSE(entry
->content_state().empty());
1219 // Test that NavigationEntries have the correct content state after opening
1220 // a new window to about:blank. Prevents regression for bug 1116137.
1221 TEST_F(WebContentsTest
, NavigationEntryContentStateNewWindow
) {
1222 TestRenderViewHost
* orig_rvh
= contents
->rvh();
1224 // When opening a new window, it is navigated to about:blank internally.
1225 // Currently, this results in two DidNavigate events.
1226 const GURL
url("about:blank");
1227 ViewHostMsg_FrameNavigate_Params params1
;
1228 InitNavigateParams(¶ms1
, 1, url
);
1229 contents
->TestDidNavigate(orig_rvh
, params1
);
1230 contents
->TestDidNavigate(orig_rvh
, params1
);
1232 // Should have a content state here.
1233 NavigationEntry
* entry
= contents
->controller()->GetLastCommittedEntry();
1234 EXPECT_FALSE(entry
->content_state().empty());
1237 // Tests to see that webkit preferences are properly loaded and copied over
1238 // to a WebPreferences object.
1239 TEST_F(WebContentsTest
, WebKitPrefs
) {
1240 WebPreferences webkit_prefs
= contents
->TestGetWebkitPrefs();
1242 // These values have been overridden by the profile preferences.
1243 EXPECT_EQ(L
"UTF-8", webkit_prefs
.default_encoding
);
1244 EXPECT_EQ(20, webkit_prefs
.default_font_size
);
1245 EXPECT_EQ(false, webkit_prefs
.text_areas_are_resizable
);
1246 EXPECT_EQ(true, webkit_prefs
.uses_universal_detector
);
1248 // These should still be the default values.
1249 EXPECT_EQ(L
"Times New Roman", webkit_prefs
.standard_font_family
);
1250 EXPECT_EQ(true, webkit_prefs
.javascript_enabled
);