| Index: chrome/browser/sessions/session_restore_browsertest.cc
|
| ===================================================================
|
| --- chrome/browser/sessions/session_restore_browsertest.cc (revision 133679)
|
| +++ chrome/browser/sessions/session_restore_browsertest.cc (working copy)
|
| @@ -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 {
|
| +#if defined(OS_MACOSX)
|
| +#include "base/mac/scoped_nsautorelease_pool.h"
|
| +#endif
|
|
|
| -// 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());
|
| -}
|
| +class SessionRestoreTest : public InProcessBrowserTest {
|
| + protected:
|
|
|
| -void CloseBrowserSynchronously(Browser* browser) {
|
| - ui_test_utils::WindowedNotificationObserver observer(
|
| - chrome::NOTIFICATION_BROWSER_CLOSED,
|
| - content::NotificationService::AllSources());
|
| - browser->window()->Close();
|
| - observer.Wait();
|
| -}
|
| + 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
|
| + }
|
|
|
| -} // namespace
|
| -
|
| -class SessionRestoreTest : public InProcessBrowserTest {
|
| - protected:
|
| 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 @@
|
| // 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 @@
|
| // 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 @@
|
| 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());
|
| +}
|
|
|