1 // Copyright (c) 2012 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. 4 5 #include "base/command_line.h" 6 #include "chrome/browser/ui/browser.h" 7 #include "chrome/browser/ui/browser_commands.h" 8 #include "chrome/browser/ui/tabs/tab_strip_model.h" 9 #include "chrome/common/chrome_switches.h" 10 #include "chrome/common/url_constants.h" 11 #include "chrome/test/base/in_process_browser_test.h" 12 #include "chrome/test/base/ui_test_utils.h" 13 #include "content/public/browser/render_process_host.h" 14 #include "content/public/browser/web_contents.h" 15 #include "content/public/test/browser_test_utils.h" 16 #include "content/public/test/test_navigation_observer.h" 17 #include "url/gurl.h" 18 19 using content::OpenURLParams; 20 using content::Referrer; 21 22 class NewTabUIBrowserTest : public InProcessBrowserTest { 23 public: 24 NewTabUIBrowserTest() {} 25 }; 26 27 // TODO(samarth): delete along with rest of NTP4 code. 28 // #if defined(OS_WIN) 29 // // Flaky on Windows (http://crbug.com/174819) 30 // #define MAYBE_LoadNTPInExistingProcess DISABLED_LoadNTPInExistingProcess 31 // #else 32 // #define MAYBE_LoadNTPInExistingProcess LoadNTPInExistingProcess 33 // #endif 34 35 // Ensure loading a NTP with an existing SiteInstance in a reused process 36 // doesn't cause us to kill the process. See http://crbug.com/104258. 37 IN_PROC_BROWSER_TEST_F(NewTabUIBrowserTest, DISABLED_LoadNTPInExistingProcess) { 38 // Set max renderers to 1 to force running out of processes. 39 content::RenderProcessHost::SetMaxRendererProcessCount(1); 40 41 // Start server for simple page. 42 ASSERT_TRUE(test_server()->Start()); 43 44 // Load a NTP in a new tab. 45 ui_test_utils::NavigateToURLWithDisposition( 46 browser(), GURL(chrome::kChromeUINewTabURL), NEW_FOREGROUND_TAB, 47 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 48 EXPECT_EQ(1, 49 browser()->tab_strip_model()->GetWebContentsAt(1)->GetMaxPageID()); 50 51 // Navigate that tab to another site. This allows the NTP process to exit, 52 // but it keeps the NTP SiteInstance (and its max_page_id) alive in history. 53 { 54 // Wait not just for the navigation to finish, but for the NTP process to 55 // exit as well. 56 content::RenderProcessHostWatcher process_exited_observer( 57 browser()->tab_strip_model()->GetActiveWebContents(), 58 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION); 59 browser()->OpenURL(OpenURLParams( 60 test_server()->GetURL("files/title1.html"), Referrer(), CURRENT_TAB, 61 content::PAGE_TRANSITION_TYPED, false)); 62 process_exited_observer.Wait(); 63 } 64 65 // Creating a NTP in another tab should not be affected, since page IDs 66 // are now specific to a tab. 67 ui_test_utils::NavigateToURLWithDisposition( 68 browser(), GURL(chrome::kChromeUINewTabURL), NEW_FOREGROUND_TAB, 69 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 70 EXPECT_EQ(1, 71 browser()->tab_strip_model()->GetWebContentsAt(2)->GetMaxPageID()); 72 chrome::CloseTab(browser()); 73 74 // Open another Web UI page in a new tab. 75 ui_test_utils::NavigateToURLWithDisposition( 76 browser(), GURL(chrome::kChromeUISettingsURL), NEW_FOREGROUND_TAB, 77 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 78 EXPECT_EQ(1, 79 browser()->tab_strip_model()->GetWebContentsAt(2)->GetMaxPageID()); 80 81 // At this point, opening another NTP will use the existing WebUI process 82 // but its own SiteInstance, so the page IDs shouldn't affect each other. 83 ui_test_utils::NavigateToURLWithDisposition( 84 browser(), GURL(chrome::kChromeUINewTabURL), NEW_FOREGROUND_TAB, 85 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 86 EXPECT_EQ(1, 87 browser()->tab_strip_model()->GetWebContentsAt(3)->GetMaxPageID()); 88 89 // Navigating to the NTP in the original tab causes a BrowsingInstance 90 // swap, so it gets a new SiteInstance starting with page ID 1 again. 91 browser()->tab_strip_model()->ActivateTabAt(1, true); 92 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); 93 EXPECT_EQ(1, 94 browser()->tab_strip_model()->GetWebContentsAt(1)->GetMaxPageID()); 95 } 96 97 // TODO(samarth): delete along with rest of NTP4 code. 98 // Loads chrome://hang/ into two NTP tabs, ensuring we don't crash. 99 // See http://crbug.com/59859. 100 // If this flakes, use http://crbug.com/87200. 101 IN_PROC_BROWSER_TEST_F(NewTabUIBrowserTest, DISABLED_ChromeHangInNTP) { 102 // Bring up a new tab page. 103 ui_test_utils::NavigateToURLWithDisposition( 104 browser(), GURL(chrome::kChromeUINewTabURL), NEW_FOREGROUND_TAB, 105 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 106 107 // Navigate to chrome://hang/ to stall the process. 108 ui_test_utils::NavigateToURLWithDisposition( 109 browser(), GURL(content::kChromeUIHangURL), CURRENT_TAB, 0); 110 111 // Visit chrome://hang/ again in another NTP. Don't bother waiting for the 112 // NTP to load, because it's hung. 113 chrome::NewTab(browser()); 114 browser()->OpenURL(OpenURLParams( 115 GURL(content::kChromeUIHangURL), Referrer(), CURRENT_TAB, 116 content::PAGE_TRANSITION_TYPED, false)); 117 } 118 119 class NewTabUIProcessPerTabTest : public NewTabUIBrowserTest { 120 public: 121 NewTabUIProcessPerTabTest() {} 122 123 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 124 command_line->AppendSwitch(switches::kProcessPerTab); 125 } 126 }; 127 128 // Navigates away from NTP before it commits, in process-per-tab mode. 129 // Ensures that we don't load the normal page in the NTP process (and thus 130 // crash), as in http://crbug.com/69224. 131 // If this flakes, use http://crbug.com/87200 132 IN_PROC_BROWSER_TEST_F(NewTabUIProcessPerTabTest, NavBeforeNTPCommits) { 133 // Bring up a new tab page. 134 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); 135 136 // Navigate to chrome://hang/ to stall the process. 137 ui_test_utils::NavigateToURLWithDisposition( 138 browser(), GURL(content::kChromeUIHangURL), CURRENT_TAB, 0); 139 140 // Visit a normal URL in another NTP that hasn't committed. 141 ui_test_utils::NavigateToURLWithDisposition( 142 browser(), GURL(chrome::kChromeUINewTabURL), NEW_FOREGROUND_TAB, 0); 143 144 // We don't use ui_test_utils::NavigateToURLWithDisposition because that waits 145 // for current loading to stop. 146 content::TestNavigationObserver observer( 147 browser()->tab_strip_model()->GetActiveWebContents()); 148 browser()->OpenURL(OpenURLParams( 149 GURL("data:text/html,hello world"), Referrer(), CURRENT_TAB, 150 content::PAGE_TRANSITION_TYPED, false)); 151 observer.Wait(); 152 } 153