Home | History | Annotate | Download | only in sessions
      1 // Copyright (c) 2011 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 "base/file_path.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/string_number_conversions.h"
      9 #include "base/test/test_timeouts.h"
     10 #include "chrome/app/chrome_command_ids.h"
     11 #include "chrome/browser/defaults.h"
     12 #include "chrome/common/chrome_paths.h"
     13 #include "chrome/common/chrome_switches.h"
     14 #include "chrome/test/automation/tab_proxy.h"
     15 #include "chrome/test/automation/browser_proxy.h"
     16 #include "chrome/test/automation/window_proxy.h"
     17 #include "chrome/test/ui/ui_test.h"
     18 #include "googleurl/src/gurl.h"
     19 #include "net/base/net_util.h"
     20 #include "net/test/test_server.h"
     21 
     22 namespace {
     23 
     24 class SessionRestoreUITest : public UITest {
     25  protected:
     26   SessionRestoreUITest() : UITest() {
     27     FilePath path_prefix = test_data_directory_.AppendASCII("session_history");
     28 
     29     url1_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot1.html"));
     30     url2_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot2.html"));
     31     url3_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot3.html"));
     32   }
     33 
     34   virtual void QuitBrowserAndRestore(int expected_tab_count) {
     35 #if defined(OS_MACOSX)
     36     set_shutdown_type(ProxyLauncher::USER_QUIT);
     37 #endif
     38     UITest::TearDown();
     39 
     40     clear_profile_ = false;
     41 
     42     launch_arguments_.AppendSwitchASCII(switches::kRestoreLastSession,
     43                                         base::IntToString(expected_tab_count));
     44     UITest::SetUp();
     45   }
     46 
     47   void CloseWindow(int window_index, int initial_count) {
     48     scoped_refptr<BrowserProxy> browser_proxy(
     49         automation()->GetBrowserWindow(window_index));
     50     ASSERT_TRUE(browser_proxy.get());
     51     ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW));
     52     int window_count;
     53     ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
     54     ASSERT_EQ(initial_count - 1, window_count);
     55   }
     56 
     57   void AssertOneWindowWithOneTab() {
     58     int window_count;
     59     ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
     60     ASSERT_EQ(1, window_count);
     61     GURL url;
     62     AssertWindowHasOneTab(0, &url);
     63   }
     64 
     65   void AssertWindowHasOneTab(int window_index, GURL* url) {
     66     scoped_refptr<BrowserProxy> browser_proxy(
     67         automation()->GetBrowserWindow(window_index));
     68     ASSERT_TRUE(browser_proxy.get());
     69 
     70     int tab_count;
     71     ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
     72     ASSERT_EQ(1, tab_count);
     73 
     74     int active_tab_index;
     75     ASSERT_TRUE(browser_proxy->GetActiveTabIndex(&active_tab_index));
     76     ASSERT_EQ(0, active_tab_index);
     77 
     78     scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetActiveTab());
     79     ASSERT_TRUE(tab_proxy.get());
     80     ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
     81         TestTimeouts::action_max_timeout_ms()));
     82 
     83     ASSERT_TRUE(tab_proxy->GetCurrentURL(url));
     84   }
     85 
     86   GURL url1_;
     87   GURL url2_;
     88   GURL url3_;
     89 
     90  private:
     91   DISALLOW_COPY_AND_ASSIGN(SessionRestoreUITest);
     92 };
     93 
     94 TEST_F(SessionRestoreUITest, Basic) {
     95   NavigateToURL(url1_);
     96   NavigateToURL(url2_);
     97 
     98   QuitBrowserAndRestore(1);
     99 
    100   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
    101   // active windows returns NULL.
    102   int window_count;
    103   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    104   ASSERT_EQ(1, window_count);
    105   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
    106   ASSERT_TRUE(browser_proxy.get());
    107   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
    108   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
    109       TestTimeouts::action_max_timeout_ms()));
    110 
    111   ASSERT_EQ(url2_, GetActiveTabURL());
    112   ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->GoBack());
    113   ASSERT_EQ(url1_, GetActiveTabURL());
    114 }
    115 
    116 TEST_F(SessionRestoreUITest, RestoresForwardAndBackwardNavs) {
    117   NavigateToURL(url1_);
    118   NavigateToURL(url2_);
    119   NavigateToURL(url3_);
    120 
    121   scoped_refptr<TabProxy> active_tab(GetActiveTab());
    122   ASSERT_TRUE(active_tab.get());
    123   ASSERT_TRUE(active_tab->GoBack());
    124 
    125   QuitBrowserAndRestore(1);
    126 
    127   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
    128   // active windows returns NULL.
    129   int window_count;
    130   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    131   ASSERT_EQ(1, window_count);
    132   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
    133   ASSERT_TRUE(browser_proxy.get());
    134   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
    135   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
    136       TestTimeouts::action_max_timeout_ms()));
    137 
    138   ASSERT_TRUE(GetActiveTabURL() == url2_);
    139   ASSERT_TRUE(tab_proxy->GoForward());
    140   ASSERT_TRUE(GetActiveTabURL() == url3_);
    141   ASSERT_TRUE(tab_proxy->GoBack());
    142   ASSERT_TRUE(GetActiveTabURL() == url2_);
    143   ASSERT_TRUE(tab_proxy->GoBack());
    144   ASSERT_TRUE(GetActiveTabURL() == url1_);
    145 }
    146 
    147 // Tests that the SiteInstances used for entries in a restored tab's history
    148 // are given appropriate max page IDs, so that going back to a restored
    149 // cross-site page and then forward again works.  (Bug 1204135)
    150 TEST_F(SessionRestoreUITest, RestoresCrossSiteForwardAndBackwardNavs) {
    151   net::TestServer test_server(net::TestServer::TYPE_HTTP,
    152                               FilePath(FILE_PATH_LITERAL("chrome/test/data")));
    153   ASSERT_TRUE(test_server.Start());
    154 
    155   GURL cross_site_url(test_server.GetURL("files/title2.html"));
    156 
    157   // Visit URLs on different sites.
    158   NavigateToURL(url1_);
    159   NavigateToURL(cross_site_url);
    160   NavigateToURL(url2_);
    161 
    162   scoped_refptr<TabProxy> active_tab(GetActiveTab());
    163   ASSERT_TRUE(active_tab.get());
    164   ASSERT_TRUE(active_tab->GoBack());
    165 
    166   QuitBrowserAndRestore(1);
    167 
    168   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
    169   // active windows returns NULL.
    170   int window_count;
    171   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    172   ASSERT_EQ(1, window_count);
    173   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
    174   ASSERT_TRUE(browser_proxy.get());
    175   int tab_count;
    176   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
    177   ASSERT_EQ(1, tab_count);
    178   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
    179   ASSERT_TRUE(tab_proxy.get());
    180   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
    181       TestTimeouts::action_max_timeout_ms()));
    182 
    183   // Check that back and forward work as expected.
    184   GURL url;
    185   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
    186   ASSERT_EQ(cross_site_url, url);
    187 
    188   ASSERT_TRUE(tab_proxy->GoBack());
    189   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
    190   ASSERT_EQ(url1_, url);
    191 
    192   ASSERT_TRUE(tab_proxy->GoForward());
    193   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
    194   ASSERT_EQ(cross_site_url, url);
    195 
    196   ASSERT_TRUE(tab_proxy->GoForward());
    197   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
    198   ASSERT_EQ(url2_, url);
    199 }
    200 
    201 TEST_F(SessionRestoreUITest, TwoTabsSecondSelected) {
    202   NavigateToURL(url1_);
    203 
    204   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
    205   // active windows returns NULL.
    206   int window_count;
    207   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    208   ASSERT_EQ(1, window_count);
    209   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
    210   ASSERT_TRUE(browser_proxy.get());
    211 
    212   ASSERT_TRUE(browser_proxy->AppendTab(url2_));
    213 
    214   QuitBrowserAndRestore(2);
    215   browser_proxy = NULL;
    216 
    217   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    218   ASSERT_EQ(1, window_count);
    219   browser_proxy = automation()->GetBrowserWindow(0);
    220 
    221   int tab_count;
    222   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
    223   ASSERT_EQ(2, tab_count);
    224 
    225   int active_tab_index;
    226   ASSERT_TRUE(browser_proxy->GetActiveTabIndex(&active_tab_index));
    227   ASSERT_EQ(1, active_tab_index);
    228 
    229   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetActiveTab());
    230   ASSERT_TRUE(tab_proxy.get());
    231   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
    232       TestTimeouts::action_max_timeout_ms()));
    233 
    234   ASSERT_EQ(url2_, GetActiveTabURL());
    235 
    236   ASSERT_TRUE(browser_proxy->ActivateTab(0));
    237   tab_proxy = browser_proxy->GetActiveTab();
    238   ASSERT_TRUE(tab_proxy.get());
    239   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
    240       TestTimeouts::action_max_timeout_ms()));
    241 
    242   ASSERT_EQ(url1_, GetActiveTabURL());
    243 }
    244 
    245 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
    246 TEST_F(SessionRestoreUITest, ClosedTabStaysClosed) {
    247   NavigateToURL(url1_);
    248 
    249   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
    250   // active windows returns NULL.
    251   int window_count;
    252   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    253   ASSERT_EQ(1, window_count);
    254   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
    255   ASSERT_TRUE(browser_proxy.get());
    256   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
    257   ASSERT_TRUE(tab_proxy.get());
    258 
    259   ASSERT_TRUE(browser_proxy->AppendTab(url2_));
    260 
    261   scoped_refptr<TabProxy> active_tab(browser_proxy->GetActiveTab());
    262   ASSERT_TRUE(active_tab.get());
    263   ASSERT_TRUE(active_tab->Close(true));
    264 
    265   QuitBrowserAndRestore(1);
    266   browser_proxy = NULL;
    267   tab_proxy = NULL;
    268 
    269   AssertOneWindowWithOneTab();
    270 
    271   ASSERT_EQ(url1_, GetActiveTabURL());
    272 }
    273 
    274 // Creates a tabbed browser and popup and makes sure we restore both.
    275 TEST_F(SessionRestoreUITest, NormalAndPopup) {
    276   if (!browser_defaults::kRestorePopups)
    277     return;  // Test only applicable if restoring popups.
    278 
    279   NavigateToURL(url1_);
    280 
    281   // Make sure we have one window.
    282   int window_count;
    283   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    284   ASSERT_EQ(1, window_count);
    285 
    286   // Open a popup.
    287   ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_POPUP,
    288                                                  true));
    289   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    290   ASSERT_EQ(2, window_count);
    291 
    292   scoped_refptr<BrowserProxy> popup(automation()->GetBrowserWindow(1));
    293   ASSERT_TRUE(popup.get());
    294 
    295   scoped_refptr<TabProxy> tab(popup->GetTab(0));
    296   ASSERT_TRUE(tab.get());
    297 
    298   ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(url1_));
    299 
    300   // Simulate an exit by shuting down the session service. If we don't do this
    301   // the first window close is treated as though the user closed the window
    302   // and won't be restored.
    303   ASSERT_TRUE(popup->ShutdownSessionService());
    304 
    305   tab = NULL;
    306   popup = NULL;
    307 
    308   // Restart and make sure we have only one window with one tab and the url
    309   // is url1_.
    310   QuitBrowserAndRestore(1);
    311 
    312   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    313   ASSERT_EQ(2, window_count);
    314 
    315   scoped_refptr<BrowserProxy> browser_proxy1(
    316       automation()->GetBrowserWindow(0));
    317   ASSERT_TRUE(browser_proxy1.get());
    318 
    319   scoped_refptr<BrowserProxy> browser_proxy2(
    320       automation()->GetBrowserWindow(1));
    321   ASSERT_TRUE(browser_proxy2.get());
    322 
    323   Browser::Type type1, type2;
    324   ASSERT_TRUE(browser_proxy1->GetType(&type1));
    325   ASSERT_TRUE(browser_proxy2->GetType(&type2));
    326 
    327   // The order of whether the normal window or popup is first depends upon
    328   // activation order, which is not necessarily consistant across runs.
    329   if (type1 == Browser::TYPE_NORMAL) {
    330     EXPECT_EQ(type2, Browser::TYPE_POPUP);
    331   } else {
    332     EXPECT_EQ(type1, Browser::TYPE_POPUP);
    333     EXPECT_EQ(type2, Browser::TYPE_NORMAL);
    334   }
    335 }
    336 
    337 #if !defined(OS_MACOSX)
    338 // This test doesn't apply to the Mac version; see
    339 // LaunchAnotherBrowserBlockUntilClosed for details.
    340 
    341 // Launches an app window, closes tabbed browser, launches and makes sure
    342 // we restore the tabbed browser url.
    343 // Flaky: http://crbug.com/29110
    344 TEST_F(SessionRestoreUITest,
    345        FLAKY_RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
    346   NavigateToURL(url1_);
    347 
    348   // Launch an app.
    349 
    350   bool include_testing_id_orig = include_testing_id_;
    351   include_testing_id_ = false;
    352   clear_profile_ = false;
    353   CommandLine app_launch_arguments = launch_arguments_;
    354   app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
    355   LaunchAnotherBrowserBlockUntilClosed(app_launch_arguments);
    356   ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
    357 
    358   // Close the first window. The only window left is the App window.
    359   CloseWindow(0, 2);
    360 
    361   // Restore the session, which should bring back the first window with url1_.
    362   // First restore the settings so we can connect to the browser.
    363   include_testing_id_ = include_testing_id_orig;
    364   // Restore the session with 1 tab.
    365   QuitBrowserAndRestore(1);
    366 
    367   AssertOneWindowWithOneTab();
    368 
    369   ASSERT_EQ(url1_, GetActiveTabURL());
    370 }
    371 
    372 #endif  // !OS_MACOSX
    373 
    374 // Creates two windows, closes one, restores, make sure only one window open.
    375 TEST_F(SessionRestoreUITest, TwoWindowsCloseOneRestoreOnlyOne) {
    376   NavigateToURL(url1_);
    377 
    378   // Make sure we have one window.
    379   int window_count;
    380   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    381   ASSERT_EQ(1, window_count);
    382 
    383   // Open a second window.
    384   ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL,
    385                                                  true));
    386   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
    387   ASSERT_EQ(2, window_count);
    388 
    389   // Close it.
    390   CloseWindow(1, 2);
    391 
    392   // Restart and make sure we have only one window with one tab and the url
    393   // is url1_.
    394   QuitBrowserAndRestore(1);
    395 
    396   AssertOneWindowWithOneTab();
    397 
    398   ASSERT_EQ(url1_, GetActiveTabURL());
    399 }
    400 
    401 // Make sure after a restore the number of processes matches that of the number
    402 // of processes running before the restore. This creates a new tab so that
    403 // we should have two new tabs running.  (This test will pass in both
    404 // process-per-site and process-per-site-instance, because we treat the new tab
    405 // as a special case in process-per-site-instance so that it only ever uses one
    406 // process.)
    407 //
    408 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
    409 // Unfortunately, the fix at http://codereview.chromium.org/6546078
    410 // breaks NTP background image refreshing, so ThemeSource had to revert to
    411 // replacing the existing data source.
    412 TEST_F(SessionRestoreUITest, FLAKY_ShareProcessesOnRestore) {
    413   if (ProxyLauncher::in_process_renderer()) {
    414     // No point in running this test in single process mode.
    415     return;
    416   }
    417 
    418   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
    419   ASSERT_TRUE(browser_proxy.get() != NULL);
    420   int tab_count;
    421   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
    422 
    423   // Create two new tabs.
    424   ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_TAB));
    425   ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_TAB));
    426   int new_tab_count;
    427   ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count));
    428   ASSERT_EQ(tab_count + 2, new_tab_count);
    429 
    430   int expected_process_count = 0;
    431   ASSERT_TRUE(GetBrowserProcessCount(&expected_process_count));
    432   int expected_tab_count = new_tab_count;
    433 
    434   // Restart.
    435   browser_proxy = NULL;
    436   QuitBrowserAndRestore(3);
    437 
    438   // Wait for each tab to finish being restored, then make sure the process
    439   // count matches.
    440   browser_proxy = automation()->GetBrowserWindow(0);
    441   ASSERT_TRUE(browser_proxy.get() != NULL);
    442   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
    443   ASSERT_EQ(expected_tab_count, tab_count);
    444 
    445   for (int i = 0; i < expected_tab_count; ++i) {
    446     scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(i));
    447     ASSERT_TRUE(tab_proxy.get() != NULL);
    448     ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
    449                     TestTimeouts::action_max_timeout_ms()));
    450   }
    451 
    452   int process_count = 0;
    453   ASSERT_TRUE(GetBrowserProcessCount(&process_count));
    454   ASSERT_EQ(expected_process_count, process_count);
    455 }
    456 
    457 }  // namespace
    458