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