OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/logging.h" | 5 #include "base/logging.h" |
6 #include "base/utf_string_conversions.h" | 6 #include "base/utf_string_conversions.h" |
7 #include "chrome/browser/dom_operation_notification_details.h" | 7 #include "chrome/browser/dom_operation_notification_details.h" |
8 #include "chrome/browser/prefs/pref_service.h" | 8 #include "chrome/browser/prefs/pref_service.h" |
9 #include "chrome/browser/tab_contents/chrome_interstitial_page.h" | 9 #include "chrome/browser/tab_contents/chrome_interstitial_page.h" |
10 #include "chrome/common/pref_names.h" | 10 #include "chrome/common/pref_names.h" |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 PageTransition::AUTO_SUBFRAME); | 707 PageTransition::AUTO_SUBFRAME); |
708 EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack()); | 708 EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack()); |
709 | 709 |
710 // Now simulate the onbeforeunload approval and verify the navigation is | 710 // Now simulate the onbeforeunload approval and verify the navigation is |
711 // not canceled. | 711 // not canceled. |
712 orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true)); | 712 orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true)); |
713 EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack()); | 713 EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack()); |
714 EXPECT_TRUE(contents()->cross_navigation_pending()); | 714 EXPECT_TRUE(contents()->cross_navigation_pending()); |
715 } | 715 } |
716 | 716 |
717 // Test that the original renderer can preempt a cross-site navigation while the | 717 // Test that a cross-site navigation is not preempted if the previous |
718 // beforeunload request is in flight. | 718 // renderer sends a FrameNavigate message just before being told to stop. |
719 TEST_F(TabContentsTest, CrossSitePreemptDuringBeforeUnload) { | 719 // We should only preempt the cross-site navigation if the previous renderer |
| 720 // has started a new navigation. See http://crbug.com/79176. |
| 721 TEST_F(TabContentsTest, CrossSiteNotPreemptedDuringBeforeUnload) { |
720 contents()->transition_cross_site = true; | 722 contents()->transition_cross_site = true; |
| 723 |
| 724 // Navigate to NTP URL. |
| 725 const GURL url("chrome://newtab"); |
| 726 controller().LoadURL(url, GURL(), PageTransition::TYPED); |
721 TestRenderViewHost* orig_rvh = rvh(); | 727 TestRenderViewHost* orig_rvh = rvh(); |
722 SiteInstance* instance1 = contents()->GetSiteInstance(); | 728 EXPECT_FALSE(contents()->cross_navigation_pending()); |
723 | 729 |
724 // Navigate to URL. First URL should use first RenderViewHost. | 730 // Navigate to new site, with the beforeunload request in flight. |
725 const GURL url("http://www.google.com"); | |
726 controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
727 ViewHostMsg_FrameNavigate_Params params1; | |
728 InitNavigateParams(¶ms1, 1, url, PageTransition::TYPED); | |
729 contents()->TestDidNavigate(orig_rvh, params1); | |
730 EXPECT_FALSE(contents()->cross_navigation_pending()); | |
731 EXPECT_EQ(orig_rvh, contents()->render_view_host()); | |
732 | |
733 // Navigate to new site, with the befureunload request in flight. | |
734 const GURL url2("http://www.yahoo.com"); | 731 const GURL url2("http://www.yahoo.com"); |
735 controller().LoadURL(url2, GURL(), PageTransition::TYPED); | 732 controller().LoadURL(url2, GURL(), PageTransition::TYPED); |
| 733 TestRenderViewHost* pending_rvh = contents()->pending_rvh(); |
| 734 EXPECT_TRUE(contents()->cross_navigation_pending()); |
| 735 EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack()); |
736 | 736 |
737 // Suppose the original renderer navigates now, while the beforeunload request | 737 // Suppose the first navigation tries to commit now, with a |
738 // is in flight. We must cancel the pending navigation and show this new | 738 // ViewMsg_Stop in flight. This should not cancel the pending navigation, |
739 // page, because the beforeunload handler might return false. | 739 // but it should act as if the beforeunload ack arrived. |
740 orig_rvh->SendNavigate(2, GURL("http://www.google.com/foo")); | 740 orig_rvh->SendNavigate(1, GURL("chrome://newtab")); |
| 741 EXPECT_TRUE(contents()->cross_navigation_pending()); |
| 742 EXPECT_EQ(orig_rvh, contents()->render_view_host()); |
| 743 EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack()); |
741 | 744 |
742 // Verify that the pending navigation is cancelled. | 745 // The pending navigation should be able to commit successfully. |
743 SiteInstance* instance2 = contents()->GetSiteInstance(); | 746 ViewHostMsg_FrameNavigate_Params params2; |
| 747 InitNavigateParams(¶ms2, 1, url2, PageTransition::TYPED); |
| 748 contents()->TestDidNavigate(pending_rvh, params2); |
744 EXPECT_FALSE(contents()->cross_navigation_pending()); | 749 EXPECT_FALSE(contents()->cross_navigation_pending()); |
745 EXPECT_EQ(orig_rvh, rvh()); | 750 EXPECT_EQ(pending_rvh, contents()->render_view_host()); |
746 EXPECT_EQ(instance1, instance2); | |
747 EXPECT_TRUE(contents()->pending_rvh() == NULL); | |
748 | |
749 // Make sure the beforeunload ack doesn't cause problems if it arrives here. | |
750 orig_rvh->TestOnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true)); | |
751 } | 751 } |
752 | 752 |
753 // Test that the original renderer cannot preempt a cross-site navigation once | 753 // Test that the original renderer cannot preempt a cross-site navigation once |
754 // the unload request has been made. At this point, the cross-site navigation | 754 // the unload request has been made. At this point, the cross-site navigation |
755 // is almost ready to be displayed, and the original renderer is only given a | 755 // is almost ready to be displayed, and the original renderer is only given a |
756 // short chance to run an unload handler. Prevents regression of bug 23942. | 756 // short chance to run an unload handler. Prevents regression of bug 23942. |
757 TEST_F(TabContentsTest, CrossSiteCantPreemptAfterUnload) { | 757 TEST_F(TabContentsTest, CrossSiteCantPreemptAfterUnload) { |
758 contents()->transition_cross_site = true; | 758 contents()->transition_cross_site = true; |
759 TestRenderViewHost* orig_rvh = rvh(); | 759 TestRenderViewHost* orig_rvh = rvh(); |
760 SiteInstance* instance1 = contents()->GetSiteInstance(); | 760 SiteInstance* instance1 = contents()->GetSiteInstance(); |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 window.close_count = 0; | 1752 window.close_count = 0; |
1753 | 1753 |
1754 const int kWindowCount = 4; | 1754 const int kWindowCount = 4; |
1755 for (int i = 0; i < kWindowCount; i++) { | 1755 for (int i = 0; i < kWindowCount; i++) { |
1756 tab_contents->AddConstrainedDialog(&window); | 1756 tab_contents->AddConstrainedDialog(&window); |
1757 } | 1757 } |
1758 EXPECT_EQ(window.close_count, 0); | 1758 EXPECT_EQ(window.close_count, 0); |
1759 delete tab_contents; | 1759 delete tab_contents; |
1760 EXPECT_EQ(window.close_count, kWindowCount); | 1760 EXPECT_EQ(window.close_count, kWindowCount); |
1761 } | 1761 } |
OLD | NEW |