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