Logo Search packages:      
Sourcecode: chromium-browser version File versions  Download package

session_restore_uitest.cc

// Copyright (c) 2006-2008 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/scoped_ptr.h"
#include "base/string_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/defaults.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_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/url_request/url_request_unittest.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_MACOSX)
    shutdown_type_ = UITestBase::USER_QUIT;
#endif
    UITest::TearDown();

    clear_profile_ = false;

    launch_arguments_.AppendSwitchWithValue(switches::kRestoreLastSession,
                                            IntToWString(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(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(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(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_);
  ASSERT_TRUE(tab_proxy->GoBack());
  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) {
  const wchar_t kDocRoot[] = L"chrome/test/data";
  scoped_refptr<HTTPTestServer> server =
      HTTPTestServer::CreateServer(kDocRoot, NULL);
  ASSERT_TRUE(NULL != server.get());
  GURL cross_site_url(server->TestServerPage("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(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);

  ASSERT_TRUE(tab_proxy->GoForward());
  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(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(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());
}

// 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_NORMAL) {
    EXPECT_EQ(type2, Browser::TYPE_POPUP);
  } else {
    EXPECT_EQ(type1, Browser::TYPE_POPUP);
    EXPECT_EQ(type2, Browser::TYPE_NORMAL);
  }
}

#if defined(OS_MACOSX)
// Fails an SQL assertion on Mac: http://crbug.com/45108
#define DontRestoreWhileIncognito DISABLED_DontRestoreWhileIncognito
#endif
// Creates a browser, goes incognito, closes browser, launches and make sure
// we don't restore.
//
TEST_F(SessionRestoreUITest, DontRestoreWhileIncognito) {
  NavigateToURL(url1_);

  // Make sure we have one window.
  int initial_window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&initial_window_count));
  ASSERT_EQ(1, initial_window_count);

  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser_proxy.get());

  // Create an off the record window.
  ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_INCOGNITO_WINDOW));
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(2, window_count);

  // Close the first window.
  CloseWindow(0, 2);
  browser_proxy = NULL;

  // Launch the browser again. Note, this doesn't spawn a new process, instead
  // it attaches to the current process.
  include_testing_id_ = false;
  clear_profile_ = false;
  launch_arguments_.AppendSwitch(switches::kRestoreLastSession);
  LaunchAnotherBrowserBlockUntilClosed(launch_arguments_);

  // A new window should appear;
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));

  // And it shouldn't have url1_ in it.
  browser_proxy = automation()->GetBrowserWindow(1);
  ASSERT_TRUE(browser_proxy.get());
  scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
  ASSERT_TRUE(tab_proxy.get());
  ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(action_max_timeout_ms()));
  GURL url;
  ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
  ASSERT_TRUE(url != url1_);
}

// 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_NORMAL,
                                                 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());
}

#if defined(OS_MACOSX)
// Fails an SQL assertion on Mac: http://crbug.com/45108
#define FLAKY_RestoreAfterClosingTabbedBrowserWithAppAndLaunching \
    DISABLED_RestoreAfterClosingTabbedBrowserWithAppAndLaunching
#endif
// Launches an app window, closes tabbed browser, launches and makes sure
// we restore the tabbed browser url.
TEST_F(SessionRestoreUITest,
       FLAKY_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.AppendSwitchWithValue(switches::kApp,
                                             UTF8ToWide(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());
}

// 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.)
TEST_F(SessionRestoreUITest, ShareProcessesOnRestore) {
  if (in_process_renderer()) {
    // No point in running this test in single process mode.
    return;
  }

  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 = GetBrowserProcessCount();
  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);

  scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(tab_count - 2));
  ASSERT_TRUE(tab_proxy.get() != NULL);
  ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(action_max_timeout_ms()));
  tab_proxy = browser_proxy->GetTab(tab_count - 1);
  ASSERT_TRUE(tab_proxy.get() != NULL);
  ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(action_max_timeout_ms()));

  ASSERT_EQ(expected_process_count, GetBrowserProcessCount());
}

}  // namespace

Generated by  Doxygen 1.6.0   Back to index