diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/chrome_main_browsertest.cc | 59 | ||||
-rw-r--r-- | chrome/browser/sessions/session_restore_browsertest.cc | 392 | ||||
-rw-r--r-- | chrome/browser/sessions/session_restore_uitest.cc | 491 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service.cc | 12 | ||||
-rw-r--r-- | chrome/browser/sessions/session_service.h | 8 |
5 files changed, 395 insertions, 567 deletions
diff --git a/chrome/browser/chrome_main_browsertest.cc b/chrome/browser/chrome_main_browsertest.cc index 888079c..5f38cb2 100644 --- a/chrome/browser/chrome_main_browsertest.cc +++ b/chrome/browser/chrome_main_browsertest.cc @@ -8,7 +8,6 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/process_util.h" -#include "base/test/test_suite.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/common/chrome_notification_types.h" @@ -20,52 +19,25 @@ #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" -#include "content/test/test_launcher.h" #include "net/base/net_util.h" -// These tests don't apply to the Mac version; see -// LaunchAnotherBrowserBlockUntilClosed for details. +// These tests don't apply to the Mac version; see GetCommandLineForRelaunch +// for details. #if !defined(OS_MACOSX) class ChromeMainTest : public InProcessBrowserTest { public: - ChromeMainTest() - : InProcessBrowserTest(), - new_command_line_(CommandLine::ForCurrentProcess()->GetProgram()) { - } - - virtual void SetUpOnMainThread() OVERRIDE { - CommandLine::SwitchMap switches = - CommandLine::ForCurrentProcess()->GetSwitches(); - switches.erase(switches::kUserDataDir); - switches.erase(test_launcher::kGTestFilterFlag); - - for (CommandLine::SwitchMap::const_iterator iter = switches.begin(); - iter != switches.end(); ++iter) { - new_command_line_.AppendSwitchNative((*iter).first, (*iter).second); - } - - FilePath user_data_dir; - PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); - new_command_line_.AppendSwitchPath(switches::kUserDataDir, user_data_dir); + ChromeMainTest() {} - new_command_line_.AppendSwitchASCII( - test_launcher::kGTestFilterFlag, test_launcher::kEmptyTestName); - new_command_line_.AppendSwitch(TestSuite::kSilent); + void Relaunch(const CommandLine& new_command_line) { + base::LaunchProcess(new_command_line, base::LaunchOptions(), NULL); } - - void Relaunch() { - base::LaunchProcess(new_command_line_, base::LaunchOptions(), NULL); - } - - protected: - CommandLine new_command_line_; }; // Make sure that the second invocation creates a new window. IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunch) { ui_test_utils::BrowserAddedObserver observer; - Relaunch(); + Relaunch(GetCommandLineForRelaunch()); observer.WaitForSingleNewBrowser(); ASSERT_EQ(BrowserList::GetBrowserCount(browser()->profile()), 2u); } @@ -73,11 +45,12 @@ IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunch) { IN_PROC_BROWSER_TEST_F(ChromeMainTest, ReuseBrowserInstanceWhenOpeningFile) { FilePath test_file_path = ui_test_utils::GetTestFilePath( FilePath(), FilePath().AppendASCII("empty.html")); - new_command_line_.AppendArgPath(test_file_path); + CommandLine new_command_line(GetCommandLineForRelaunch()); + new_command_line.AppendArgPath(test_file_path); ui_test_utils::WindowedNotificationObserver observer( chrome::NOTIFICATION_TAB_ADDED, content::NotificationService::AllSources()); - Relaunch(); + Relaunch(new_command_line); observer.Wait(); GURL url = net::FilePathToFileURL(test_file_path); @@ -94,14 +67,15 @@ IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunchWithIncognitoUrl) { // Run with --incognito switch and an URL specified. FilePath test_file_path = ui_test_utils::GetTestFilePath( FilePath(), FilePath().AppendASCII("empty.html")); - new_command_line_.AppendSwitch(switches::kIncognito); - new_command_line_.AppendArgPath(test_file_path); + CommandLine new_command_line(GetCommandLineForRelaunch()); + new_command_line.AppendSwitch(switches::kIncognito); + new_command_line.AppendArgPath(test_file_path); - Relaunch(); + Relaunch(new_command_line); // There should be one normal and one incognito window now. ui_test_utils::BrowserAddedObserver observer; - Relaunch(); + Relaunch(new_command_line); observer.WaitForSingleNewBrowser(); ASSERT_EQ(2u, BrowserList::size()); @@ -136,11 +110,12 @@ IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunchFromIncognitoWithNormalUrl) { // Run with just an URL specified, no --incognito switch. FilePath test_file_path = ui_test_utils::GetTestFilePath( FilePath(), FilePath().AppendASCII("empty.html")); - new_command_line_.AppendArgPath(test_file_path); + CommandLine new_command_line(GetCommandLineForRelaunch()); + new_command_line.AppendArgPath(test_file_path); ui_test_utils::WindowedNotificationObserver tab_observer( chrome::NOTIFICATION_TAB_ADDED, content::NotificationService::AllSources()); - Relaunch(); + Relaunch(new_command_line); tab_observer.Wait(); // There should be one normal and one incognito window now. diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 76f9797..cf29893 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc @@ -5,6 +5,7 @@ #include "base/command_line.h" #include "base/file_path.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/defaults.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/profiles/profile.h" @@ -21,47 +22,140 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/common/url_constants.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/page_transition_types.h" +#include "content/test/test_navigation_observer.h" -namespace { - -// Verifies that the given NavigationController has exactly two entries that -// correspond to the given URLs. -void VerifyNavigationEntries( - content::NavigationController& controller, GURL url1, GURL url2) { - ASSERT_EQ(2, controller.GetEntryCount()); - EXPECT_EQ(1, controller.GetCurrentEntryIndex()); - EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); - EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL()); -} - -void CloseBrowserSynchronously(Browser* browser) { - ui_test_utils::WindowedNotificationObserver observer( - chrome::NOTIFICATION_BROWSER_CLOSED, - content::NotificationService::AllSources()); - browser->window()->Close(); - observer.Wait(); -} - -} // namespace +#if defined(OS_MACOSX) +#include "base/mac/scoped_nsautorelease_pool.h" +#endif class SessionRestoreTest : public InProcessBrowserTest { protected: + + virtual void SetUpOnMainThread() OVERRIDE { + SessionStartupPref pref(SessionStartupPref::LAST); + SessionStartupPref::SetStartupPref(browser()->profile(), pref); +#if defined(OS_CHROMEOS) || defined(OS_MACOSX) + const testing::TestInfo* const test_info = + testing::UnitTest::GetInstance()->current_test_info(); + if (strcmp(test_info->name(), "NoSessionRestoreNewWindowChromeOS")) { + // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we + // can get these test to work without quitting. + SessionServiceFactory::GetForProfile(browser()->profile())-> + force_browser_not_alive_with_no_windows_ = true; + } +#endif + } + virtual bool SetUpUserDataDirectory() OVERRIDE { // Make sure the first run sentinel file exists before running these tests, // since some of them customize the session startup pref whose value can // be different than the default during the first run. // TODO(bauerb): set the first run flag instead of creating a sentinel file. first_run::CreateSentinel(); + + url1_ = ui_test_utils::GetTestUrl( + FilePath().AppendASCII("session_history"), + FilePath().AppendASCII("bot1.html")); + url2_ = ui_test_utils::GetTestUrl( + FilePath().AppendASCII("session_history"), + FilePath().AppendASCII("bot2.html")); + url3_ = ui_test_utils::GetTestUrl( + FilePath().AppendASCII("session_history"), + FilePath().AppendASCII("bot3.html")); + return InProcessBrowserTest::SetUpUserDataDirectory(); } + + // Verifies that the given NavigationController has exactly two entries that + // correspond to the given URLs. + void VerifyNavigationEntries( + content::NavigationController& controller, GURL url1, GURL url2) { + ASSERT_EQ(2, controller.GetEntryCount()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); + EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL()); + } + + void CloseBrowserSynchronously(Browser* browser) { + ui_test_utils::WindowedNotificationObserver observer( + chrome::NOTIFICATION_BROWSER_CLOSED, + content::NotificationService::AllSources()); + browser->window()->Close(); +#if defined(OS_MACOSX) + // BrowserWindowController depends on the auto release pool being recycled + // in the message loop to delete itself, which frees the Browser object + // which fires this event. + AutoreleasePool()->Recycle(); +#endif + observer.Wait(); + } + + Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) { + // Create a new popup. + Profile* profile = browser->profile(); + + // Close the browser. + g_browser_process->AddRefModule(); + CloseBrowserSynchronously(browser); + + // Create a new window, which should trigger session restore. + ui_test_utils::BrowserAddedObserver window_observer; + TestNavigationObserver navigation_observer( + content::NotificationService::AllSources(), NULL, expected_tab_count); + Browser::NewEmptyWindow(profile); + Browser* new_browser = window_observer.WaitForSingleNewBrowser(); + navigation_observer.Wait(); + g_browser_process->ReleaseModule(); + + return new_browser; + } + + void GoBack(Browser* browser) { + ui_test_utils::WindowedNotificationObserver observer( + content::NOTIFICATION_LOAD_STOP, + content::NotificationService::AllSources()); + browser->GoBack(CURRENT_TAB); + observer.Wait(); + } + + void GoForward(Browser* browser) { + ui_test_utils::WindowedNotificationObserver observer( + content::NOTIFICATION_LOAD_STOP, + content::NotificationService::AllSources()); + browser->GoForward(CURRENT_TAB); + observer.Wait(); + } + + void AssertOneWindowWithOneTab(Browser* browser) { + ASSERT_EQ(1u, BrowserList::size()); + ASSERT_EQ(1, browser->tab_count()); + } + + int RenderProcessHostCount() { + content::RenderProcessHost::iterator hosts = + content::RenderProcessHost::AllHostsIterator(); + int count = 0; + while (!hosts.IsAtEnd()) { + if (hosts.GetCurrentValue()->HasConnection()) + count++; + hosts.Advance(); + } + return count; + } + + GURL url1_; + GURL url2_; + GURL url3_; }; #if defined(OS_CHROMEOS) @@ -74,10 +168,6 @@ class SessionRestoreTest : public InProcessBrowserTest { // not do session restore if an incognito window is already open. // (http://crbug.com/120927) IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) { - // Turn on session restore. - SessionStartupPref pref(SessionStartupPref::LAST); - SessionStartupPref::SetStartupPref(browser()->profile(), pref); - GURL url(ui_test_utils::GetTestUrl( FilePath(FilePath::kCurrentDirectory), FilePath(FILE_PATH_LITERAL("title1.html")))); @@ -255,10 +345,6 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) { // Verifies we remember the last browser window when closing the last // non-incognito window while an incognito window is open. IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) { - // Turn on session restore. - SessionStartupPref pref(SessionStartupPref::LAST); - SessionStartupPref::SetStartupPref(browser()->profile(), pref); - GURL url(ui_test_utils::GetTestUrl( FilePath(FilePath::kCurrentDirectory), FilePath(FILE_PATH_LITERAL("title1.html")))); @@ -339,3 +425,251 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) { VerifyNavigationEntries( new_browser->GetWebContentsAt(0)->GetController(), url1, url2); } + +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) { + ui_test_utils::NavigateToURL(browser(), url1_); + ui_test_utils::NavigateToURL(browser(), url2_); + + Browser* new_browser = QuitBrowserAndRestore(browser(), 1); + ASSERT_EQ(1u, BrowserList::size()); + ASSERT_EQ(url2_, new_browser->GetSelectedWebContents()->GetURL()); + GoBack(new_browser); + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); +} + +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) { + ui_test_utils::NavigateToURL(browser(), url1_); + ui_test_utils::NavigateToURL(browser(), url2_); + ui_test_utils::NavigateToURL(browser(), url3_); + + GoBack(browser()); + Browser* new_browser = QuitBrowserAndRestore(browser(), 1); + ASSERT_EQ(1u, BrowserList::size()); + ASSERT_EQ(url2_, new_browser->GetSelectedWebContents()->GetURL()); + GoForward(new_browser); + ASSERT_EQ(url3_, new_browser->GetSelectedWebContents()->GetURL()); + GoBack(new_browser); + ASSERT_EQ(url2_, new_browser->GetSelectedWebContents()->GetURL()); + + // Test renderer-initiated back/forward as well. + GURL go_back_url("javascript:history.back();"); + ui_test_utils::NavigateToURL(new_browser, go_back_url); + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); +} + +// Tests that the SiteInstances used for entries in a restored tab's history +// are given appropriate max page IDs, so that going back to a restored +// cross-site page and then forward again works. (Bug 1204135) +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, + RestoresCrossSiteForwardAndBackwardNavs) { + ASSERT_TRUE(test_server()->Start()); + + GURL cross_site_url(test_server()->GetURL("files/title2.html")); + + // Visit URLs on different sites. + ui_test_utils::NavigateToURL(browser(), url1_); + ui_test_utils::NavigateToURL(browser(), cross_site_url); + ui_test_utils::NavigateToURL(browser(), url2_); + + GoBack(browser()); + Browser* new_browser = QuitBrowserAndRestore(browser(), 1); + ASSERT_EQ(1u, BrowserList::size()); + ASSERT_EQ(1, new_browser->tab_count()); + + // Check that back and forward work as expected. + ASSERT_EQ(cross_site_url, new_browser->GetSelectedWebContents()->GetURL()); + + GoBack(new_browser); + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); + + GoForward(new_browser); + ASSERT_EQ(cross_site_url, new_browser->GetSelectedWebContents()->GetURL()); + + // Test renderer-initiated back/forward as well. + GURL go_forward_url("javascript:history.forward();"); + ui_test_utils::NavigateToURL(new_browser, go_forward_url); + ASSERT_EQ(url2_, new_browser->GetSelectedWebContents()->GetURL()); +} + +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) { + ui_test_utils::NavigateToURL(browser(), url1_); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url2_, NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + Browser* new_browser = QuitBrowserAndRestore(browser(), 2); + + ASSERT_EQ(1u, BrowserList::size()); + ASSERT_EQ(2, new_browser->tab_count()); + ASSERT_EQ(1, new_browser->active_index()); + ASSERT_EQ(url2_, new_browser->GetSelectedWebContents()->GetURL()); + + ASSERT_EQ(url1_, new_browser->GetWebContentsAt(0)->GetURL()); +} + +// Creates two tabs, closes one, quits and makes sure only one tab is restored. +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) { + ui_test_utils::NavigateToURL(browser(), url1_); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url2_, NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + browser()->CloseTab(); + + Browser* new_browser = QuitBrowserAndRestore(browser(), 1); + + AssertOneWindowWithOneTab(new_browser); + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); +} + +// Test to verify that the print preview tab is not restored. +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, DontRestorePrintPreviewTabTest) { + ui_test_utils::NavigateToURL(browser(), url1_); + + // Append the print preview tab. + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL(chrome::kChromeUIPrintURL), NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + // Restart and make sure we have only one window with one tab and the url + // is url1_. + Browser* new_browser = QuitBrowserAndRestore(browser(), 1); + + AssertOneWindowWithOneTab(new_browser); + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); +} + +// Creates a tabbed browser and popup and makes sure we restore both. +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NormalAndPopup) { + if (!browser_defaults::kRestorePopups) + return; // Test only applicable if restoring popups. + + ui_test_utils::NavigateToURL(browser(), url1_); + + // Make sure we have one window. + AssertOneWindowWithOneTab(browser()); + + // Open a popup. + Browser* popup = Browser::CreateWithParams( + Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); + popup->window()->Show(); + ASSERT_EQ(2u, BrowserList::size()); + + ui_test_utils::NavigateToURL(popup, url1_); + + // Simulate an exit by shuting down the session service. If we don't do this + // the first window close is treated as though the user closed the window + // and won't be restored. + SessionServiceFactory::ShutdownForProfile(browser()->profile()); + + // Restart and make sure we have two windows. + QuitBrowserAndRestore(browser(), 1); + + ASSERT_EQ(2u, BrowserList::size()); + + Browser* browser1 = *BrowserList::begin(); + Browser* browser2 = *(++BrowserList::begin()); + + Browser::Type type1 = browser1->type(); + Browser::Type type2 = browser2->type(); + + // The order of whether the normal window or popup is first depends upon + // activation order, which is not necessarily consistant across runs. + if (type1 == Browser::TYPE_TABBED) { + EXPECT_EQ(type2, Browser::TYPE_POPUP); + } else { + EXPECT_EQ(type1, Browser::TYPE_POPUP); + EXPECT_EQ(type2, Browser::TYPE_TABBED); + } +} + +#if !defined(OS_CHROMEOS) && !defined(OS_MACOSX) +// This test doesn't apply to the Mac version; see GetCommandLineForRelaunch +// for details. It was disabled for a long time so might never have worked on +// ChromeOS. + +// Launches an app window, closes tabbed browser, launches and makes sure +// we restore the tabbed browser url. +// If this test flakes, use http://crbug.com/29110 +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, + RestoreAfterClosingTabbedBrowserWithAppAndLaunching) { + ui_test_utils::NavigateToURL(browser(), url1_); + + // Launch an app. + CommandLine app_launch_arguments = GetCommandLineForRelaunch(); + app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec()); + + ui_test_utils::BrowserAddedObserver window_observer; + + base::LaunchProcess(app_launch_arguments, base::LaunchOptions(), NULL); + + Browser* app_window = window_observer.WaitForSingleNewBrowser(); + ASSERT_EQ(2u, BrowserList::size()); + + // Close the first window. The only window left is the App window. + CloseBrowserSynchronously(browser()); + + // Restore the session, which should bring back the first window with url1_. + Browser* new_browser = QuitBrowserAndRestore(app_window, 1); + + AssertOneWindowWithOneTab(new_browser); + + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); +} + +#endif // !defined(OS_CHROMEOS) && !defined(OS_MACOSX) + +// Creates two windows, closes one, restores, make sure only one window open. +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) { + ui_test_utils::NavigateToURL(browser(), url1_); + + // Open a second window. + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL(chrome::kAboutBlankURL), NEW_WINDOW, + ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); + + ASSERT_EQ(2u, BrowserList::size()); + + // Close it. + Browser* new_window = *(++BrowserList::begin()); + CloseBrowserSynchronously(new_window); + + // Restart and make sure we have only one window with one tab and the url + // is url1_. + Browser* new_browser = QuitBrowserAndRestore(browser(), 1); + + AssertOneWindowWithOneTab(new_browser); + + ASSERT_EQ(url1_, new_browser->GetSelectedWebContents()->GetURL()); +} + +// Make sure after a restore the number of processes matches that of the number +// of processes running before the restore. This creates a new tab so that +// we should have two new tabs running. (This test will pass in both +// process-per-site and process-per-site-instance, because we treat the new tab +// as a special case in process-per-site-instance so that it only ever uses one +// process.) +// +// Flaky: http://code.google.com/p/chromium/issues/detail?id=52022 +// Unfortunately, the fix at http://codereview.chromium.org/6546078 +// breaks NTP background image refreshing, so ThemeSource had to revert to +// replacing the existing data source. +IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) { + // Create two new tabs. + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL(chrome::kAboutBlankURL), NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL(chrome::kAboutBlankURL), NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + int expected_process_count = RenderProcessHostCount(); + + // Restart. + Browser* new_browser = QuitBrowserAndRestore(browser(), 3); + + ASSERT_EQ(3, new_browser->tab_count()); + + ASSERT_EQ(expected_process_count, RenderProcessHostCount()); +} diff --git a/chrome/browser/sessions/session_restore_uitest.cc b/chrome/browser/sessions/session_restore_uitest.cc deleted file mode 100644 index d3d3a01..0000000 --- a/chrome/browser/sessions/session_restore_uitest.cc +++ /dev/null @@ -1,491 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/command_line.h" -#include "base/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_number_conversions.h" -#include "base/test/test_timeouts.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/defaults.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/automation/automation_proxy.h" -#include "chrome/test/automation/browser_proxy.h" -#include "chrome/test/automation/tab_proxy.h" -#include "chrome/test/automation/window_proxy.h" -#include "chrome/test/ui/ui_test.h" -#include "googleurl/src/gurl.h" -#include "net/base/net_util.h" -#include "net/test/test_server.h" - -namespace { - -class SessionRestoreUITest : public UITest { - protected: - SessionRestoreUITest() : UITest() { - FilePath path_prefix = test_data_directory_.AppendASCII("session_history"); - - url1_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot1.html")); - url2_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot2.html")); - url3_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot3.html")); - } - - virtual void QuitBrowserAndRestore(int expected_tab_count) { -#if defined(OS_CHROMEOS) || defined(OS_MACOSX) - set_shutdown_type(ProxyLauncher::USER_QUIT); -#endif - UITest::TearDown(); - - clear_profile_ = false; - - // Clear launch_arguments so that the URL arg doesn't get added on restart. - launch_arguments_ = CommandLine(launch_arguments_.GetProgram()); - - launch_arguments_.AppendSwitchASCII(switches::kRestoreLastSession, - base::IntToString(expected_tab_count)); - UITest::SetUp(); - } - - void CloseWindow(int window_index, int initial_count) { - scoped_refptr<BrowserProxy> browser_proxy( - automation()->GetBrowserWindow(window_index)); - ASSERT_TRUE(browser_proxy.get()); - ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW)); - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(initial_count - 1, window_count); - } - - void AssertOneWindowWithOneTab() { - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - GURL url; - AssertWindowHasOneTab(0, &url); - } - - void AssertWindowHasOneTab(int window_index, GURL* url) { - scoped_refptr<BrowserProxy> browser_proxy( - automation()->GetBrowserWindow(window_index)); - ASSERT_TRUE(browser_proxy.get()); - - int tab_count; - ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); - ASSERT_EQ(1, tab_count); - - int active_tab_index; - ASSERT_TRUE(browser_proxy->GetActiveTabIndex(&active_tab_index)); - ASSERT_EQ(0, active_tab_index); - - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetActiveTab()); - ASSERT_TRUE(tab_proxy.get()); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - - ASSERT_TRUE(tab_proxy->GetCurrentURL(url)); - } - - GURL url1_; - GURL url2_; - GURL url3_; - - private: - DISALLOW_COPY_AND_ASSIGN(SessionRestoreUITest); -}; - -TEST_F(SessionRestoreUITest, Basic) { - NavigateToURL(url1_); - NavigateToURL(url2_); - - QuitBrowserAndRestore(1); - - // NOTE: Don't use GetActiveWindow here, when run with the screen locked - // active windows returns NULL. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get()); - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0)); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - - ASSERT_EQ(url2_, GetActiveTabURL()); - ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->GoBack()); - ASSERT_EQ(url1_, GetActiveTabURL()); -} - -TEST_F(SessionRestoreUITest, RestoresForwardAndBackwardNavs) { - NavigateToURL(url1_); - NavigateToURL(url2_); - NavigateToURL(url3_); - - scoped_refptr<TabProxy> active_tab(GetActiveTab()); - ASSERT_TRUE(active_tab.get()); - ASSERT_TRUE(active_tab->GoBack()); - - QuitBrowserAndRestore(1); - - // NOTE: Don't use GetActiveWindow here, when run with the screen locked - // active windows returns NULL. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get()); - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0)); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - - ASSERT_TRUE(GetActiveTabURL() == url2_); - ASSERT_TRUE(tab_proxy->GoForward()); - ASSERT_TRUE(GetActiveTabURL() == url3_); - ASSERT_TRUE(tab_proxy->GoBack()); - ASSERT_TRUE(GetActiveTabURL() == url2_); - - // Test renderer-initiated back/forward as well. - GURL go_back_url("javascript:history.back();"); - ASSERT_TRUE(tab_proxy->NavigateToURL(go_back_url)); - ASSERT_TRUE(GetActiveTabURL() == url1_); -} - -// Tests that the SiteInstances used for entries in a restored tab's history -// are given appropriate max page IDs, so that going back to a restored -// cross-site page and then forward again works. (Bug 1204135) -TEST_F(SessionRestoreUITest, RestoresCrossSiteForwardAndBackwardNavs) { - net::TestServer test_server(net::TestServer::TYPE_HTTP, - net::TestServer::kLocalhost, - FilePath(FILE_PATH_LITERAL("chrome/test/data"))); - ASSERT_TRUE(test_server.Start()); - - GURL cross_site_url(test_server.GetURL("files/title2.html")); - - // Visit URLs on different sites. - NavigateToURL(url1_); - NavigateToURL(cross_site_url); - NavigateToURL(url2_); - - scoped_refptr<TabProxy> active_tab(GetActiveTab()); - ASSERT_TRUE(active_tab.get()); - ASSERT_TRUE(active_tab->GoBack()); - - QuitBrowserAndRestore(1); - - // NOTE: Don't use GetActiveWindow here, when run with the screen locked - // active windows returns NULL. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get()); - int tab_count; - ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); - ASSERT_EQ(1, tab_count); - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0)); - ASSERT_TRUE(tab_proxy.get()); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - - // Check that back and forward work as expected. - GURL url; - ASSERT_TRUE(tab_proxy->GetCurrentURL(&url)); - ASSERT_EQ(cross_site_url, url); - - ASSERT_TRUE(tab_proxy->GoBack()); - ASSERT_TRUE(tab_proxy->GetCurrentURL(&url)); - ASSERT_EQ(url1_, url); - - ASSERT_TRUE(tab_proxy->GoForward()); - ASSERT_TRUE(tab_proxy->GetCurrentURL(&url)); - ASSERT_EQ(cross_site_url, url); - - // Test renderer-initiated back/forward as well. - GURL go_forward_url("javascript:history.forward();"); - ASSERT_TRUE(tab_proxy->NavigateToURL(go_forward_url)); - ASSERT_TRUE(tab_proxy->GetCurrentURL(&url)); - ASSERT_EQ(url2_, url); -} - -TEST_F(SessionRestoreUITest, TwoTabsSecondSelected) { - NavigateToURL(url1_); - - // NOTE: Don't use GetActiveWindow here, when run with the screen locked - // active windows returns NULL. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get()); - - ASSERT_TRUE(browser_proxy->AppendTab(url2_)); - - QuitBrowserAndRestore(2); - browser_proxy = NULL; - - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - browser_proxy = automation()->GetBrowserWindow(0); - - int tab_count; - ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); - ASSERT_EQ(2, tab_count); - - int active_tab_index; - ASSERT_TRUE(browser_proxy->GetActiveTabIndex(&active_tab_index)); - ASSERT_EQ(1, active_tab_index); - - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetActiveTab()); - ASSERT_TRUE(tab_proxy.get()); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - - ASSERT_EQ(url2_, GetActiveTabURL()); - - ASSERT_TRUE(browser_proxy->ActivateTab(0)); - tab_proxy = browser_proxy->GetActiveTab(); - ASSERT_TRUE(tab_proxy.get()); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - - ASSERT_EQ(url1_, GetActiveTabURL()); -} - -// Creates two tabs, closes one, quits and makes sure only one tab is restored. -TEST_F(SessionRestoreUITest, ClosedTabStaysClosed) { - NavigateToURL(url1_); - - // NOTE: Don't use GetActiveWindow here, when run with the screen locked - // active windows returns NULL. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get()); - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0)); - ASSERT_TRUE(tab_proxy.get()); - - ASSERT_TRUE(browser_proxy->AppendTab(url2_)); - - scoped_refptr<TabProxy> active_tab(browser_proxy->GetActiveTab()); - ASSERT_TRUE(active_tab.get()); - ASSERT_TRUE(active_tab->Close(true)); - - QuitBrowserAndRestore(1); - browser_proxy = NULL; - tab_proxy = NULL; - - AssertOneWindowWithOneTab(); - - ASSERT_EQ(url1_, GetActiveTabURL()); -} - -// Test to verify that the print preview tab is not restored. -TEST_F(SessionRestoreUITest, DontRestorePrintPreviewTabTest) { - NavigateToURL(url1_); - - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get()); - - // Append the print preview tab. - GURL printPreviewURL(chrome::kChromeUIPrintURL); - ASSERT_TRUE(browser_proxy->AppendTab(printPreviewURL)); - - scoped_refptr<TabProxy> active_tab(browser_proxy->GetActiveTab()); - ASSERT_TRUE(active_tab.get()); - ASSERT_EQ(printPreviewURL, GetActiveTabURL()); - - // Restart and make sure we have only one window with one tab and the url - // is url1_. - QuitBrowserAndRestore(1); - browser_proxy = NULL; - - AssertOneWindowWithOneTab(); - - ASSERT_EQ(url1_, GetActiveTabURL()); -} - -// Creates a tabbed browser and popup and makes sure we restore both. -TEST_F(SessionRestoreUITest, NormalAndPopup) { - if (!browser_defaults::kRestorePopups) - return; // Test only applicable if restoring popups. - - NavigateToURL(url1_); - - // Make sure we have one window. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - - // Open a popup. - ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_POPUP, - true)); - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(2, window_count); - - scoped_refptr<BrowserProxy> popup(automation()->GetBrowserWindow(1)); - ASSERT_TRUE(popup.get()); - - scoped_refptr<TabProxy> tab(popup->GetTab(0)); - ASSERT_TRUE(tab.get()); - - ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(url1_)); - - // Simulate an exit by shuting down the session service. If we don't do this - // the first window close is treated as though the user closed the window - // and won't be restored. - ASSERT_TRUE(popup->ShutdownSessionService()); - - tab = NULL; - popup = NULL; - - // Restart and make sure we have only one window with one tab and the url - // is url1_. - QuitBrowserAndRestore(1); - - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(2, window_count); - - scoped_refptr<BrowserProxy> browser_proxy1( - automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy1.get()); - - scoped_refptr<BrowserProxy> browser_proxy2( - automation()->GetBrowserWindow(1)); - ASSERT_TRUE(browser_proxy2.get()); - - Browser::Type type1, type2; - ASSERT_TRUE(browser_proxy1->GetType(&type1)); - ASSERT_TRUE(browser_proxy2->GetType(&type2)); - - // The order of whether the normal window or popup is first depends upon - // activation order, which is not necessarily consistant across runs. - if (type1 == Browser::TYPE_TABBED) { - EXPECT_EQ(type2, Browser::TYPE_POPUP); - } else { - EXPECT_EQ(type1, Browser::TYPE_POPUP); - EXPECT_EQ(type2, Browser::TYPE_TABBED); - } -} - -#if !defined(OS_MACOSX) -// This test doesn't apply to the Mac version; see -// LaunchAnotherBrowserBlockUntilClosed for details. - -// Launches an app window, closes tabbed browser, launches and makes sure -// we restore the tabbed browser url. -// Flaky: http://crbug.com/29110 -TEST_F(SessionRestoreUITest, - DISABLED_RestoreAfterClosingTabbedBrowserWithAppAndLaunching) { - NavigateToURL(url1_); - - // Launch an app. - - bool include_testing_id_orig = include_testing_id_; - include_testing_id_ = false; - clear_profile_ = false; - CommandLine app_launch_arguments = launch_arguments_; - app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec()); - LaunchAnotherBrowserBlockUntilClosed(app_launch_arguments); - ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2)); - - // Close the first window. The only window left is the App window. - CloseWindow(0, 2); - - // Restore the session, which should bring back the first window with url1_. - // First restore the settings so we can connect to the browser. - include_testing_id_ = include_testing_id_orig; - // Restore the session with 1 tab. - QuitBrowserAndRestore(1); - - AssertOneWindowWithOneTab(); - - ASSERT_EQ(url1_, GetActiveTabURL()); -} - -#endif // !OS_MACOSX - -// Creates two windows, closes one, restores, make sure only one window open. -TEST_F(SessionRestoreUITest, TwoWindowsCloseOneRestoreOnlyOne) { - NavigateToURL(url1_); - - // Make sure we have one window. - int window_count; - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(1, window_count); - - // Open a second window. - ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_TABBED, - true)); - ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - ASSERT_EQ(2, window_count); - - // Close it. - CloseWindow(1, 2); - - // Restart and make sure we have only one window with one tab and the url - // is url1_. - QuitBrowserAndRestore(1); - - AssertOneWindowWithOneTab(); - - ASSERT_EQ(url1_, GetActiveTabURL()); -} - -// Make sure after a restore the number of processes matches that of the number -// of processes running before the restore. This creates a new tab so that -// we should have two new tabs running. (This test will pass in both -// process-per-site and process-per-site-instance, because we treat the new tab -// as a special case in process-per-site-instance so that it only ever uses one -// process.) -// -// Flaky: http://code.google.com/p/chromium/issues/detail?id=52022 -// Unfortunately, the fix at http://codereview.chromium.org/6546078 -// breaks NTP background image refreshing, so ThemeSource had to revert to -// replacing the existing data source. -TEST_F(SessionRestoreUITest, DISABLED_ShareProcessesOnRestore) { - scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser_proxy.get() != NULL); - int tab_count; - ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); - - // Create two new tabs. - ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_TAB)); - ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_TAB)); - int new_tab_count; - ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count)); - ASSERT_EQ(tab_count + 2, new_tab_count); - - int expected_process_count = 0; - ASSERT_TRUE(GetBrowserProcessCount(&expected_process_count)); - int expected_tab_count = new_tab_count; - - // Restart. - browser_proxy = NULL; - QuitBrowserAndRestore(3); - - // Wait for each tab to finish being restored, then make sure the process - // count matches. - browser_proxy = automation()->GetBrowserWindow(0); - ASSERT_TRUE(browser_proxy.get() != NULL); - ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); - ASSERT_EQ(expected_tab_count, tab_count); - - for (int i = 0; i < expected_tab_count; ++i) { - scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(i)); - ASSERT_TRUE(tab_proxy.get() != NULL); - ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored( - TestTimeouts::action_max_timeout_ms())); - } - - int process_count = 0; - ASSERT_TRUE(GetBrowserProcessCount(&process_count)); - ASSERT_EQ(expected_process_count, process_count); -} - -} // namespace diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc index 4eb3f65..f39ec70 100644 --- a/chrome/browser/sessions/session_service.cc +++ b/chrome/browser/sessions/session_service.cc @@ -198,7 +198,8 @@ SessionService::SessionService(Profile* profile) move_on_new_browser_(false), save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), - save_delay_in_hrs_(base::TimeDelta::FromHours(8)) { + save_delay_in_hrs_(base::TimeDelta::FromHours(8)), + force_browser_not_alive_with_no_windows_(false) { Init(); } @@ -208,7 +209,8 @@ SessionService::SessionService(const FilePath& save_path) move_on_new_browser_(false), save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), - save_delay_in_hrs_(base::TimeDelta::FromHours(8)) { + save_delay_in_hrs_(base::TimeDelta::FromHours(8)), + force_browser_not_alive_with_no_windows_(false) { Init(); } @@ -525,7 +527,10 @@ bool SessionService::ShouldNewWindowStartSession() { // ChromeOS and OSX have different ideas of application lifetime than // the other platforms. // On ChromeOS opening a new window should never start a new session. -#if !defined(OS_CHROMEOS) +#if defined(OS_CHROMEOS) + if (!force_browser_not_alive_with_no_windows_) + return false; +#endif if (!has_open_trackable_browsers_ && !BrowserInit::InSynchronousProfileLaunch() && !SessionRestore::IsRestoring(profile()) @@ -537,7 +542,6 @@ bool SessionService::ShouldNewWindowStartSession() { ) { return true; } -#endif // !OS_CHROMEOS return false; } diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h index b5c5a3f..781fa9c 100644 --- a/chrome/browser/sessions/session_service.h +++ b/chrome/browser/sessions/session_service.h @@ -53,7 +53,8 @@ class NavigationEntry; // of the browser. class SessionService : public BaseSessionService, public content::NotificationObserver { - friend class SessionServiceTestHelper; + friend class SessionRestoreTest; + friend class SessionServiceTestHelper; public: // Used to distinguish an application window from a normal one. enum AppType { @@ -387,6 +388,7 @@ class SessionService : public BaseSessionService, // windows or similar. In this case, we record the close as pending. return !has_open_trackable_browsers_ && (!browser_defaults::kBrowserAliveWithNoWindows || + force_browser_not_alive_with_no_windows_ || BrowserList::size() > 1); } @@ -462,6 +464,10 @@ class SessionService : public BaseSessionService, const base::TimeDelta save_delay_in_mins_; const base::TimeDelta save_delay_in_hrs_; + // For browser_tests, since we want to simulate the browser shutting down + // without quitting. + bool force_browser_not_alive_with_no_windows_; + DISALLOW_COPY_AND_ASSIGN(SessionService); }; |