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/basictypes.h" 6 #include "base/command_line.h" 7 #include "base/file_path.h" 8 #include "base/test/test_timeouts.h" 9 #include "chrome/app/chrome_command_ids.h" 10 #include "chrome/common/chrome_paths.h" 11 #include "chrome/common/url_constants.h" 12 #include "chrome/test/automation/tab_proxy.h" 13 #include "chrome/test/automation/browser_proxy.h" 14 #include "chrome/test/automation/window_proxy.h" 15 #include "chrome/test/ui/ui_test.h" 16 #include "googleurl/src/gurl.h" 17 #include "net/base/net_util.h" 18 #include "net/test/test_server.h" 19 20 // http://code.google.com/p/chromium/issues/detail?id=14774 21 #if (defined(OS_WIN) || defined(OS_CHROMEOS)) && !defined(NDEBUG) 22 #define MAYBE_BasicRestoreFromClosedWindow DISABLED_BasicRestoreFromClosedWindow 23 #else 24 #define MAYBE_BasicRestoreFromClosedWindow BasicRestoreFromClosedWindow 25 #endif 26 27 class TabRestoreUITest : public UITest { 28 public: 29 TabRestoreUITest() : UITest() { 30 FilePath path_prefix(test_data_directory_); 31 path_prefix = path_prefix.AppendASCII("session_history"); 32 url1_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot1.html")); 33 url2_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot2.html")); 34 } 35 36 protected: 37 // Uses the undo-close-tab accelerator to undo a close-tab or close-window 38 // operation. The newly restored tab is expected to appear in the 39 // window at index |expected_window_index|, at the |expected_tabstrip_index|, 40 // and to be active. If |expected_window_index| is equal to the number of 41 // current windows, the restored tab is expected to be created in a new 42 // window (since the index is 0-based). 43 void RestoreTab(int expected_window_index, 44 int expected_tabstrip_index) { 45 int tab_count = 0; 46 int window_count = 0; 47 48 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 49 ASSERT_GT(window_count, 0); 50 51 bool expect_new_window = (expected_window_index == window_count); 52 scoped_refptr<BrowserProxy> browser_proxy; 53 if (expect_new_window) { 54 browser_proxy = automation()->GetBrowserWindow(0); 55 } else { 56 ASSERT_GT(window_count, expected_window_index); 57 browser_proxy = automation()->GetBrowserWindow(expected_window_index); 58 } 59 ASSERT_TRUE(browser_proxy.get()); 60 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 61 ASSERT_GT(tab_count, 0); 62 63 // Restore the tab. 64 ASSERT_TRUE(browser_proxy->RunCommand(IDC_RESTORE_TAB)); 65 66 if (expect_new_window) { 67 int new_window_count = 0; 68 ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count)); 69 EXPECT_EQ(++window_count, new_window_count); 70 browser_proxy = automation()->GetBrowserWindow(expected_window_index); 71 ASSERT_TRUE(browser_proxy.get()); 72 } else { 73 int new_tab_count = 0; 74 ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count)); 75 EXPECT_EQ(++tab_count, new_tab_count); 76 } 77 78 // Get a handle to the restored tab. 79 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 80 ASSERT_GT(tab_count, expected_tabstrip_index); 81 scoped_refptr<TabProxy> restored_tab_proxy( 82 browser_proxy->GetTab(expected_tabstrip_index)); 83 ASSERT_TRUE(restored_tab_proxy.get()); 84 // Wait for the restored tab to finish loading. 85 ASSERT_TRUE(restored_tab_proxy->WaitForTabToBeRestored( 86 TestTimeouts::action_max_timeout_ms())); 87 88 // Ensure that the tab and window are active. 89 CheckActiveWindow(browser_proxy.get()); 90 EXPECT_EQ(expected_tabstrip_index, 91 GetActiveTabIndex(expected_window_index)); 92 } 93 94 // Adds tabs to the given browser, all navigated to url1_. Returns 95 // the final number of tabs. 96 int AddSomeTabs(BrowserProxy* browser, int how_many) { 97 int starting_tab_count = -1; 98 EXPECT_TRUE(browser->GetTabCount(&starting_tab_count)); 99 100 for (int i = 0; i < how_many; ++i) { 101 EXPECT_TRUE(browser->AppendTab(url1_)); 102 } 103 int tab_count; 104 EXPECT_TRUE(browser->GetTabCount(&tab_count)); 105 EXPECT_EQ(starting_tab_count + how_many, tab_count); 106 return tab_count; 107 } 108 109 // Ensure that the given browser occupies the currently active window. 110 void CheckActiveWindow(const BrowserProxy* browser) { 111 // This entire check is disabled because even the IsActive() call 112 // sporadically fails to complete successfully. See http://crbug.com/10916. 113 // TODO(pamg): Investigate and re-enable. Also find a way to have the 114 // calling location reported in the gtest error, by inlining this again if 115 // nothing else. 116 return; 117 118 bool is_active = false; 119 scoped_refptr<WindowProxy> window_proxy(browser->GetWindow()); 120 ASSERT_TRUE(window_proxy.get()); 121 ASSERT_TRUE(window_proxy->IsActive(&is_active)); 122 // The check for is_active may fail if other apps are active while running 123 // the tests, because Chromium won't be the foremost application at all. 124 // So we'll have it log an error, but not report one through gtest, to 125 // keep the test result deterministic and the buildbots happy. 126 if (!is_active) 127 LOG(ERROR) << "WARNING: is_active was false, expected true. (This may " 128 "be simply because Chromium isn't the front application.)"; 129 } 130 131 GURL url1_; 132 GURL url2_; 133 134 private: 135 DISALLOW_COPY_AND_ASSIGN(TabRestoreUITest); 136 }; 137 138 // Close the end tab in the current window, then restore it. The tab should be 139 // in its original position, and active. 140 TEST_F(TabRestoreUITest, Basic) { 141 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 142 ASSERT_TRUE(browser_proxy.get()); 143 144 int starting_tab_count; 145 ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count)); 146 int tab_count = AddSomeTabs(browser_proxy.get(), 1); 147 148 int closed_tab_index = tab_count - 1; 149 scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index)); 150 ASSERT_TRUE(new_tab.get()); 151 // Make sure we're at url. 152 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_)); 153 // Close the tab. 154 ASSERT_TRUE(new_tab->Close(true)); 155 new_tab = NULL; 156 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 157 EXPECT_EQ(starting_tab_count, tab_count); 158 159 RestoreTab(0, closed_tab_index); 160 161 // And make sure everything looks right. 162 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 163 EXPECT_EQ(starting_tab_count + 1, tab_count); 164 EXPECT_EQ(closed_tab_index, GetActiveTabIndex()); 165 EXPECT_EQ(url1_, GetActiveTabURL()); 166 } 167 168 // Close a tab not at the end of the current window, then restore it. The tab 169 // should be in its original position, and active. 170 TEST_F(TabRestoreUITest, MiddleTab) { 171 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 172 ASSERT_TRUE(browser_proxy.get()); 173 174 int starting_tab_count; 175 ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count)); 176 int tab_count = AddSomeTabs(browser_proxy.get(), 3); 177 178 // Close one in the middle 179 int closed_tab_index = starting_tab_count + 1; 180 scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index)); 181 ASSERT_TRUE(new_tab.get()); 182 // Make sure we're at url. 183 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_)); 184 // Close the tab. 185 ASSERT_TRUE(new_tab->Close(true)); 186 new_tab = NULL; 187 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 188 EXPECT_EQ(starting_tab_count + 2, tab_count); 189 190 RestoreTab(0, closed_tab_index); 191 192 // And make sure everything looks right. 193 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 194 EXPECT_EQ(starting_tab_count + 3, tab_count); 195 EXPECT_EQ(closed_tab_index, GetActiveTabIndex()); 196 EXPECT_EQ(url1_, GetActiveTabURL()); 197 } 198 199 // Close a tab, switch windows, then restore the tab. The tab should be in its 200 // original window and position, and active. 201 TEST_F(TabRestoreUITest, RestoreToDifferentWindow) { 202 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 203 ASSERT_TRUE(browser_proxy.get()); 204 205 // This call is virtually guaranteed to pass, assuming that Chromium is the 206 // active application, which will establish a baseline for later calls to 207 // CheckActiveWindow(). See comments in that function. 208 CheckActiveWindow(browser_proxy.get()); 209 210 int starting_tab_count; 211 ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count)); 212 int tab_count = AddSomeTabs(browser_proxy.get(), 3); 213 214 // Close one in the middle 215 int closed_tab_index = starting_tab_count + 1; 216 scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index)); 217 ASSERT_TRUE(new_tab.get()); 218 // Make sure we're at url. 219 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_)); 220 // Close the tab. 221 ASSERT_TRUE(new_tab->Close(true)); 222 new_tab = NULL; 223 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 224 EXPECT_EQ(starting_tab_count + 2, tab_count); 225 226 // Create a new browser. 227 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false)); 228 int window_count; 229 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 230 EXPECT_EQ(2, window_count); 231 232 CheckActiveWindow(automation()->GetBrowserWindow(1)); 233 234 // Restore tab into original browser. 235 RestoreTab(0, closed_tab_index); 236 237 // And make sure everything looks right. 238 CheckActiveWindow(browser_proxy.get()); 239 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 240 EXPECT_EQ(starting_tab_count + 3, tab_count); 241 EXPECT_EQ(closed_tab_index, GetActiveTabIndex(0)); 242 EXPECT_EQ(url1_, GetActiveTabURL(0)); 243 } 244 245 // Close a tab, open a new window, close the first window, then restore the 246 // tab. It should be in a new window. 247 TEST_F(TabRestoreUITest, MAYBE_BasicRestoreFromClosedWindow) { 248 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 249 ASSERT_TRUE(browser_proxy.get()); 250 CheckActiveWindow(browser_proxy.get()); 251 252 int tab_count; 253 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 254 255 // Close tabs until we only have one open. 256 while (tab_count > 1) { 257 scoped_refptr<TabProxy> tab_to_close(browser_proxy->GetTab(0)); 258 ASSERT_TRUE(tab_to_close.get()); 259 ASSERT_TRUE(tab_to_close->Close(true)); 260 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 261 } 262 263 // Navigate to url1 then url2. 264 scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0)); 265 ASSERT_TRUE(tab_proxy.get()); 266 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->NavigateToURL(url1_)); 267 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->NavigateToURL(url2_)); 268 269 // Create a new browser. 270 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false)); 271 int window_count; 272 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 273 EXPECT_EQ(2, window_count); 274 CheckActiveWindow(automation()->GetBrowserWindow(1)); 275 276 // Close the final tab in the first browser. 277 EXPECT_TRUE(tab_proxy->Close(true)); 278 ASSERT_TRUE(automation()->WaitForWindowCountToBecome(1)); 279 280 // Tab and browser are no longer valid. 281 tab_proxy = NULL; 282 browser_proxy = NULL; 283 284 RestoreTab(1, 0); 285 286 // Tab should be in a new window. 287 browser_proxy = automation()->GetBrowserWindow(1); 288 ASSERT_TRUE(browser_proxy.get()); 289 CheckActiveWindow(browser_proxy.get()); 290 tab_proxy = browser_proxy->GetActiveTab(); 291 ASSERT_TRUE(tab_proxy.get()); 292 // And make sure the URLs matches. 293 EXPECT_EQ(url2_, GetActiveTabURL(1)); 294 EXPECT_TRUE(tab_proxy->GoBack()); 295 EXPECT_EQ(url1_, GetActiveTabURL(1)); 296 } 297 298 // Restore a tab then make sure it doesn't restore again. 299 TEST_F(TabRestoreUITest, DontLoadRestoredTab) { 300 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 301 ASSERT_TRUE(browser_proxy.get()); 302 CheckActiveWindow(browser_proxy.get()); 303 304 // Add two tabs 305 int starting_tab_count = 0; 306 ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count)); 307 AddSomeTabs(browser_proxy.get(), 2); 308 int current_tab_count = 0; 309 ASSERT_TRUE(browser_proxy->GetTabCount(¤t_tab_count)); 310 ASSERT_EQ(current_tab_count, starting_tab_count + 2); 311 312 // Close one of them. 313 scoped_refptr<TabProxy> tab_to_close(browser_proxy->GetTab(0)); 314 ASSERT_TRUE(tab_to_close.get()); 315 ASSERT_TRUE(tab_to_close->Close(true)); 316 ASSERT_TRUE(browser_proxy->GetTabCount(¤t_tab_count)); 317 ASSERT_EQ(current_tab_count, starting_tab_count + 1); 318 319 // Restore it. 320 RestoreTab(0, 0); 321 ASSERT_TRUE(browser_proxy->GetTabCount(¤t_tab_count)); 322 ASSERT_EQ(current_tab_count, starting_tab_count + 2); 323 324 // Make sure that there's nothing else to restore. 325 bool enabled; 326 ASSERT_TRUE(browser_proxy->IsMenuCommandEnabled(IDC_RESTORE_TAB, &enabled)); 327 EXPECT_FALSE(enabled); 328 } 329 330 // Open a window with multiple tabs, close a tab, then close the window. 331 // Restore both and make sure the tab goes back into the window. 332 TEST_F(TabRestoreUITest, RestoreWindowAndTab) { 333 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 334 ASSERT_TRUE(browser_proxy.get()); 335 CheckActiveWindow(browser_proxy.get()); 336 337 int starting_tab_count; 338 ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count)); 339 int tab_count = AddSomeTabs(browser_proxy.get(), 3); 340 341 // Close one in the middle 342 int closed_tab_index = starting_tab_count + 1; 343 scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index)); 344 ASSERT_TRUE(new_tab.get()); 345 // Make sure we're at url. 346 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_)); 347 // Close the tab. 348 ASSERT_TRUE(new_tab->Close(true)); 349 new_tab = NULL; 350 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 351 EXPECT_EQ(starting_tab_count + 2, tab_count); 352 353 // Create a new browser. 354 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false)); 355 int window_count; 356 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 357 EXPECT_EQ(2, window_count); 358 CheckActiveWindow(automation()->GetBrowserWindow(1)); 359 360 // Close the first browser. 361 bool application_closing; 362 EXPECT_TRUE(CloseBrowser(browser_proxy.get(), &application_closing)); 363 EXPECT_FALSE(application_closing); 364 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 365 EXPECT_EQ(1, window_count); 366 367 // Browser is no longer valid. 368 browser_proxy = NULL; 369 370 // Restore the first window. The expected_tabstrip_index (second argument) 371 // indicates the expected active tab. 372 RestoreTab(1, starting_tab_count + 1); 373 browser_proxy = automation()->GetBrowserWindow(1); 374 ASSERT_TRUE(browser_proxy.get()); 375 CheckActiveWindow(browser_proxy.get()); 376 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 377 EXPECT_EQ(starting_tab_count + 2, tab_count); 378 379 // Restore the closed tab. 380 RestoreTab(1, closed_tab_index); 381 CheckActiveWindow(browser_proxy.get()); 382 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 383 EXPECT_EQ(starting_tab_count + 3, tab_count); 384 EXPECT_EQ(url1_, GetActiveTabURL(1)); 385 } 386 387 // Open a window with two tabs, close both (closing the window), then restore 388 // both. Make sure both restored tabs are in the same window. 389 TEST_F(TabRestoreUITest, RestoreIntoSameWindow) { 390 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 391 ASSERT_TRUE(browser_proxy.get()); 392 CheckActiveWindow(browser_proxy.get()); 393 394 int starting_tab_count; 395 ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count)); 396 int tab_count = AddSomeTabs(browser_proxy.get(), 2); 397 398 // Navigate the rightmost one to url2_ for easier identification. 399 scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(tab_count - 1)); 400 ASSERT_TRUE(tab_proxy.get()); 401 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->NavigateToURL(url2_)); 402 403 // Create a new browser. 404 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false)); 405 int window_count; 406 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 407 EXPECT_EQ(2, window_count); 408 CheckActiveWindow(automation()->GetBrowserWindow(1)); 409 410 // Close all but one tab in the first browser, left to right. 411 while (tab_count > 1) { 412 scoped_refptr<TabProxy> tab_to_close(browser_proxy->GetTab(0)); 413 ASSERT_TRUE(tab_to_close.get()); 414 ASSERT_TRUE(tab_to_close->Close(true)); 415 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 416 } 417 418 // Close the last tab, closing the browser. 419 tab_proxy = browser_proxy->GetTab(0); 420 ASSERT_TRUE(tab_proxy.get()); 421 EXPECT_TRUE(tab_proxy->Close(true)); 422 ASSERT_TRUE(automation()->WaitForWindowCountToBecome(1)); 423 browser_proxy = NULL; 424 tab_proxy = NULL; 425 426 // Restore the last-closed tab into a new window. 427 RestoreTab(1, 0); 428 browser_proxy = automation()->GetBrowserWindow(1); 429 ASSERT_TRUE(browser_proxy.get()); 430 CheckActiveWindow(browser_proxy.get()); 431 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 432 EXPECT_EQ(1, tab_count); 433 EXPECT_EQ(url2_, GetActiveTabURL(1)); 434 435 // Restore the next-to-last-closed tab into the same window. 436 RestoreTab(1, 0); 437 CheckActiveWindow(browser_proxy.get()); 438 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 439 EXPECT_EQ(2, tab_count); 440 EXPECT_EQ(url1_, GetActiveTabURL(1)); 441 } 442 443 // Tests that a duplicate history entry is not created when we restore a page 444 // to an existing SiteInstance. (Bug 1230446) 445 TEST_F(TabRestoreUITest, RestoreWithExistingSiteInstance) { 446 net::TestServer test_server(net::TestServer::TYPE_HTTP, 447 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 448 ASSERT_TRUE(test_server.Start()); 449 450 GURL http_url1(test_server.GetURL("files/title1.html")); 451 GURL http_url2(test_server.GetURL("files/title2.html")); 452 453 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 454 ASSERT_TRUE(browser_proxy.get()); 455 int tab_count; 456 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 457 458 // Add a tab 459 ASSERT_TRUE(browser_proxy->AppendTab(http_url1)); 460 int new_tab_count; 461 ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count)); 462 EXPECT_EQ(++tab_count, new_tab_count); 463 scoped_refptr<TabProxy> tab(browser_proxy->GetTab(tab_count - 1)); 464 ASSERT_TRUE(tab.get()); 465 466 // Navigate to another same-site URL. 467 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url2)); 468 469 // Close the tab. 470 ASSERT_TRUE(tab->Close(true)); 471 tab = NULL; 472 473 // Create a new tab to the original site. Assuming process-per-site is 474 // enabled, this will ensure that the SiteInstance used by the restored tab 475 // will already exist when the restore happens. 476 ASSERT_TRUE(browser_proxy->AppendTab(http_url2)); 477 478 // Restore the closed tab. 479 RestoreTab(0, tab_count - 1); 480 tab = browser_proxy->GetActiveTab(); 481 ASSERT_TRUE(tab.get()); 482 483 // And make sure the URLs match. 484 EXPECT_EQ(http_url2, GetActiveTabURL()); 485 EXPECT_TRUE(tab->GoBack()); 486 EXPECT_EQ(http_url1, GetActiveTabURL()); 487 } 488 489 // Tests that the SiteInstances used for entries in a restored tab's history 490 // are given appropriate max page IDs, even if the renderer for the entry 491 // already exists. (Bug 1204135) 492 TEST_F(TabRestoreUITest, RestoreCrossSiteWithExistingSiteInstance) { 493 net::TestServer test_server(net::TestServer::TYPE_HTTP, 494 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 495 ASSERT_TRUE(test_server.Start()); 496 497 GURL http_url1(test_server.GetURL("files/title1.html")); 498 GURL http_url2(test_server.GetURL("files/title2.html")); 499 500 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 501 ASSERT_TRUE(browser_proxy.get()); 502 int tab_count; 503 ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count)); 504 505 // Add a tab 506 ASSERT_TRUE(browser_proxy->AppendTab(http_url1)); 507 int new_tab_count; 508 ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count)); 509 EXPECT_EQ(++tab_count, new_tab_count); 510 scoped_refptr<TabProxy> tab(browser_proxy->GetTab(tab_count - 1)); 511 ASSERT_TRUE(tab.get()); 512 513 // Navigate to more URLs, then a cross-site URL. 514 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url2)); 515 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url1)); 516 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(url1_)); 517 518 // Close the tab. 519 ASSERT_TRUE(tab->Close(true)); 520 tab = NULL; 521 522 // Create a new tab to the original site. Assuming process-per-site is 523 // enabled, this will ensure that the SiteInstance will already exist when 524 // the user clicks Back in the restored tab. 525 ASSERT_TRUE(browser_proxy->AppendTab(http_url2)); 526 527 // Restore the closed tab. 528 RestoreTab(0, tab_count - 1); 529 tab = browser_proxy->GetActiveTab(); 530 ASSERT_TRUE(tab.get()); 531 532 // And make sure the URLs match. 533 EXPECT_EQ(url1_, GetActiveTabURL()); 534 EXPECT_TRUE(tab->GoBack()); 535 EXPECT_EQ(http_url1, GetActiveTabURL()); 536 537 // Navigating to a new URL should clear the forward list, because the max 538 // page ID of the renderer should have been updated when we restored the tab. 539 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url2)); 540 EXPECT_FALSE(tab->GoForward()); 541 EXPECT_EQ(http_url2, GetActiveTabURL()); 542 } 543 544 TEST_F(TabRestoreUITest, RestoreWindow) { 545 // Create a new window. 546 int window_count; 547 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 548 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false)); 549 int new_window_count = 0; 550 ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count)); 551 EXPECT_EQ(++window_count, new_window_count); 552 553 // Create two more tabs, one with url1, the other url2. 554 scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); 555 ASSERT_TRUE(browser_proxy.get()); 556 int initial_tab_count; 557 ASSERT_TRUE(browser_proxy->GetTabCount(&initial_tab_count)); 558 ASSERT_TRUE(browser_proxy->AppendTab(url1_)); 559 ASSERT_TRUE(browser_proxy->WaitForTabCountToBecome(initial_tab_count + 1)); 560 scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(initial_tab_count)); 561 ASSERT_TRUE(new_tab.get()); 562 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_)); 563 ASSERT_TRUE(browser_proxy->AppendTab(url2_)); 564 ASSERT_TRUE(browser_proxy->WaitForTabCountToBecome(initial_tab_count + 2)); 565 new_tab = browser_proxy->GetTab(initial_tab_count + 1); 566 ASSERT_TRUE(new_tab.get()); 567 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url2_)); 568 569 // Close the window. 570 ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW)); 571 browser_proxy = NULL; 572 new_tab = NULL; 573 ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count)); 574 EXPECT_EQ(window_count - 1, new_window_count); 575 576 // Restore the window. 577 browser_proxy = automation()->GetBrowserWindow(0); 578 ASSERT_TRUE(browser_proxy.get()); 579 ASSERT_TRUE(browser_proxy->RunCommand(IDC_RESTORE_TAB)); 580 ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count)); 581 EXPECT_EQ(window_count, new_window_count); 582 583 browser_proxy = automation()->GetBrowserWindow(1); 584 int tab_count; 585 EXPECT_TRUE(browser_proxy->GetTabCount(&tab_count)); 586 EXPECT_EQ(initial_tab_count + 2, tab_count); 587 588 scoped_refptr<TabProxy> restored_tab_proxy( 589 browser_proxy->GetTab(initial_tab_count)); 590 ASSERT_TRUE(restored_tab_proxy.get()); 591 ASSERT_TRUE(restored_tab_proxy->WaitForTabToBeRestored( 592 TestTimeouts::action_timeout_ms())); 593 GURL url; 594 ASSERT_TRUE(restored_tab_proxy->GetCurrentURL(&url)); 595 EXPECT_TRUE(url == url1_); 596 597 restored_tab_proxy = browser_proxy->GetTab(initial_tab_count + 1); 598 ASSERT_TRUE(restored_tab_proxy.get()); 599 ASSERT_TRUE(restored_tab_proxy->WaitForTabToBeRestored( 600 TestTimeouts::action_timeout_ms())); 601 ASSERT_TRUE(restored_tab_proxy->GetCurrentURL(&url)); 602 EXPECT_TRUE(url == url2_); 603 } 604 605 // Restore tab with special URL about:credits and make sure the page loads 606 // properly after restore. See http://crbug.com/31905. 607 TEST_F(TabRestoreUITest, RestoreTabWithSpecialURL) { 608 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); 609 ASSERT_TRUE(browser.get()); 610 CheckActiveWindow(browser.get()); 611 612 // Navigate new tab to a special URL. 613 const GURL special_url(chrome::kAboutCreditsURL); 614 ASSERT_TRUE(browser->AppendTab(special_url)); 615 scoped_refptr<TabProxy> tab(browser->GetActiveTab()); 616 ASSERT_TRUE(tab.get()); 617 618 // Close the tab. 619 ASSERT_TRUE(tab->Close(true)); 620 621 // Restore the closed tab. 622 RestoreTab(0, 1); 623 tab = browser->GetTab(1); 624 ASSERT_TRUE(tab.get()); 625 ASSERT_TRUE(tab->WaitForTabToBeRestored(TestTimeouts::action_timeout_ms())); 626 627 // See if content is as expected. 628 EXPECT_TRUE(tab->FindInPage(std::wstring(L"webkit"), FWD, IGNORE_CASE, false, 629 NULL)); 630 } 631 632 // Restore tab with special URL in its navigation history, go back to that 633 // entry and see that it loads properly. See http://crbug.com/31905 634 TEST_F(TabRestoreUITest, RestoreTabWithSpecialURLOnBack) { 635 net::TestServer test_server(net::TestServer::TYPE_HTTP, 636 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 637 ASSERT_TRUE(test_server.Start()); 638 639 const GURL http_url(test_server.GetURL("files/title1.html")); 640 641 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); 642 ASSERT_TRUE(browser.get()); 643 CheckActiveWindow(browser.get()); 644 645 // Navigate new tab to a special URL. 646 const GURL special_url(chrome::kAboutCreditsURL); 647 ASSERT_TRUE(browser->AppendTab(special_url)); 648 scoped_refptr<TabProxy> tab(browser->GetActiveTab()); 649 ASSERT_TRUE(tab.get()); 650 651 // Then navigate to a normal URL. 652 ASSERT_TRUE(tab->NavigateToURL(http_url)); 653 654 // Close the tab. 655 ASSERT_TRUE(tab->Close(true)); 656 657 // Restore the closed tab. 658 RestoreTab(0, 1); 659 tab = browser->GetTab(1); 660 ASSERT_TRUE(tab.get()); 661 ASSERT_TRUE(tab->WaitForTabToBeRestored(TestTimeouts::action_timeout_ms())); 662 GURL url; 663 ASSERT_TRUE(tab->GetCurrentURL(&url)); 664 ASSERT_EQ(http_url, url); 665 666 // Go back, and see if content is as expected. 667 ASSERT_TRUE(tab->GoBack()); 668 EXPECT_TRUE(tab->FindInPage(std::wstring(L"webkit"), FWD, IGNORE_CASE, false, 669 NULL)); 670 } 671