1 // Copyright (c) 2012 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 <vector> 6 7 #include "base/command_line.h" 8 #include "base/files/file_path.h" 9 #include "base/process/launch.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "base/time/time.h" 12 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/defaults.h" 15 #include "chrome/browser/first_run/first_run.h" 16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile_manager.h" 18 #include "chrome/browser/sessions/session_restore.h" 19 #include "chrome/browser/sessions/session_service.h" 20 #include "chrome/browser/sessions/session_service_factory.h" 21 #include "chrome/browser/sessions/session_service_test_helper.h" 22 #include "chrome/browser/sessions/session_types.h" 23 #include "chrome/browser/sessions/tab_restore_service.h" 24 #include "chrome/browser/sessions/tab_restore_service_factory.h" 25 #include "chrome/browser/ui/browser.h" 26 #include "chrome/browser/ui/browser_commands.h" 27 #include "chrome/browser/ui/browser_list.h" 28 #include "chrome/browser/ui/browser_tabstrip.h" 29 #include "chrome/browser/ui/browser_window.h" 30 #include "chrome/browser/ui/host_desktop.h" 31 #include "chrome/browser/ui/tabs/tab_strip_model.h" 32 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/url_constants.h" 34 #include "chrome/test/base/in_process_browser_test.h" 35 #include "chrome/test/base/test_switches.h" 36 #include "chrome/test/base/ui_test_utils.h" 37 #include "components/sessions/serialized_navigation_entry_test_helper.h" 38 #include "content/public/browser/navigation_controller.h" 39 #include "content/public/browser/navigation_entry.h" 40 #include "content/public/browser/notification_service.h" 41 #include "content/public/browser/notification_types.h" 42 #include "content/public/browser/render_process_host.h" 43 #include "content/public/browser/render_view_host.h" 44 #include "content/public/browser/web_contents.h" 45 #include "content/public/common/bindings_policy.h" 46 #include "content/public/test/browser_test_utils.h" 47 #include "content/public/test/test_navigation_observer.h" 48 #include "sync/protocol/session_specifics.pb.h" 49 #include "ui/base/page_transition_types.h" 50 51 using sessions::SerializedNavigationEntry; 52 using sessions::SerializedNavigationEntryTestHelper; 53 54 #if defined(OS_MACOSX) 55 #include "base/mac/scoped_nsautorelease_pool.h" 56 #endif 57 58 #if defined(USE_AURA) 59 #include "ui/aura/window.h" 60 #endif 61 62 class SessionRestoreTest : public InProcessBrowserTest { 63 public: 64 SessionRestoreTest() : active_browser_list_(NULL) {} 65 66 protected: 67 #if defined(OS_CHROMEOS) 68 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 69 // TODO(nkostylev): Investigate if we can remove this switch. 70 command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests); 71 InProcessBrowserTest::SetUpCommandLine(command_line); 72 } 73 #endif 74 75 virtual void SetUpOnMainThread() OVERRIDE { 76 active_browser_list_ = BrowserList::GetInstance(chrome::GetActiveDesktop()); 77 78 SessionStartupPref pref(SessionStartupPref::LAST); 79 SessionStartupPref::SetStartupPref(browser()->profile(), pref); 80 #if defined(OS_CHROMEOS) 81 const testing::TestInfo* const test_info = 82 testing::UnitTest::GetInstance()->current_test_info(); 83 if (strcmp(test_info->name(), "NoSessionRestoreNewWindowChromeOS") != 0) { 84 // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we 85 // can get these test to work without quitting. 86 SessionServiceTestHelper helper( 87 SessionServiceFactory::GetForProfile(browser()->profile())); 88 helper.SetForceBrowserNotAliveWithNoWindows(true); 89 helper.ReleaseService(); 90 } 91 #endif 92 93 InProcessBrowserTest::SetUpOnMainThread(); 94 } 95 96 virtual bool SetUpUserDataDirectory() OVERRIDE { 97 url1_ = ui_test_utils::GetTestUrl( 98 base::FilePath().AppendASCII("session_history"), 99 base::FilePath().AppendASCII("bot1.html")); 100 url2_ = ui_test_utils::GetTestUrl( 101 base::FilePath().AppendASCII("session_history"), 102 base::FilePath().AppendASCII("bot2.html")); 103 url3_ = ui_test_utils::GetTestUrl( 104 base::FilePath().AppendASCII("session_history"), 105 base::FilePath().AppendASCII("bot3.html")); 106 107 return InProcessBrowserTest::SetUpUserDataDirectory(); 108 } 109 110 void CloseBrowserSynchronously(Browser* browser) { 111 content::WindowedNotificationObserver observer( 112 chrome::NOTIFICATION_BROWSER_CLOSED, 113 content::NotificationService::AllSources()); 114 browser->window()->Close(); 115 #if defined(OS_MACOSX) 116 // BrowserWindowController depends on the auto release pool being recycled 117 // in the message loop to delete itself, which frees the Browser object 118 // which fires this event. 119 AutoreleasePool()->Recycle(); 120 #endif 121 observer.Wait(); 122 } 123 124 Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) { 125 return QuitBrowserAndRestoreWithURL(browser, expected_tab_count, GURL()); 126 } 127 128 Browser* QuitBrowserAndRestoreWithURL(Browser* browser, 129 int expected_tab_count, 130 const GURL& url) { 131 Profile* profile = browser->profile(); 132 133 // Close the browser. 134 g_browser_process->AddRefModule(); 135 CloseBrowserSynchronously(browser); 136 137 // Create a new window, which should trigger session restore. 138 ui_test_utils::BrowserAddedObserver window_observer; 139 content::WindowedNotificationObserver restore_observer( 140 chrome::NOTIFICATION_SESSION_RESTORE_DONE, 141 content::NotificationService::AllSources()); 142 if (url.is_empty()) { 143 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE); 144 } else { 145 chrome::NavigateParams params(profile, 146 url, 147 ui::PAGE_TRANSITION_LINK); 148 chrome::Navigate(¶ms); 149 } 150 Browser* new_browser = window_observer.WaitForSingleNewBrowser(); 151 restore_observer.Wait(); 152 g_browser_process->ReleaseModule(); 153 154 return new_browser; 155 } 156 157 void GoBack(Browser* browser) { 158 content::TestNavigationObserver observer( 159 browser->tab_strip_model()->GetActiveWebContents()); 160 chrome::GoBack(browser, CURRENT_TAB); 161 observer.Wait(); 162 } 163 164 void GoForward(Browser* browser) { 165 content::TestNavigationObserver observer( 166 browser->tab_strip_model()->GetActiveWebContents()); 167 chrome::GoForward(browser, CURRENT_TAB); 168 observer.Wait(); 169 } 170 171 void AssertOneWindowWithOneTab(Browser* browser) { 172 ASSERT_EQ(1u, active_browser_list_->size()); 173 ASSERT_EQ(1, browser->tab_strip_model()->count()); 174 } 175 176 int RenderProcessHostCount() { 177 content::RenderProcessHost::iterator hosts = 178 content::RenderProcessHost::AllHostsIterator(); 179 int count = 0; 180 while (!hosts.IsAtEnd()) { 181 if (hosts.GetCurrentValue()->HasConnection()) 182 count++; 183 hosts.Advance(); 184 } 185 return count; 186 } 187 188 GURL url1_; 189 GURL url2_; 190 GURL url3_; 191 192 const BrowserList* active_browser_list_; 193 }; 194 195 #if defined(USE_AURA) 196 // Verifies that restored tabs have a root window. This is important 197 // otherwise the wrong information is communicated to the renderer. 198 // (http://crbug.com/342672). 199 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveRootWindow) { 200 // Create tabs. 201 ui_test_utils::NavigateToURLWithDisposition( 202 browser(), 203 GURL(url::kAboutBlankURL), 204 NEW_FOREGROUND_TAB, 205 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 206 ui_test_utils::NavigateToURLWithDisposition( 207 browser(), 208 GURL(url::kAboutBlankURL), 209 NEW_BACKGROUND_TAB, 210 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 211 212 // Restart and session restore the tabs. 213 Browser* restored = QuitBrowserAndRestore(browser(), 3); 214 TabStripModel* tab_strip_model = restored->tab_strip_model(); 215 const int tabs = tab_strip_model->count(); 216 ASSERT_EQ(3, tabs); 217 218 // Check the restored tabs have a root window. 219 for (int i = 0; i < tabs; ++i) { 220 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i); 221 gfx::NativeView window = contents->GetNativeView(); 222 bool tab_has_root_window = !!window->GetRootWindow(); 223 EXPECT_TRUE(tab_has_root_window); 224 } 225 } 226 #endif // USE_AURA 227 228 // Verify that restored tabs have correct disposition. Only one tab should 229 // have "visible" visibility state, the rest should not. 230 // (http://crbug.com/155365 http://crbug.com/118269) 231 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, 232 RestoredTabsHaveCorrectVisibilityState) { 233 // Create tabs. 234 GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(), 235 base::FilePath(FILE_PATH_LITERAL("tab-restore-visibilty.html")))); 236 ui_test_utils::NavigateToURLWithDisposition( 237 browser(), test_page, NEW_FOREGROUND_TAB, 238 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 239 ui_test_utils::NavigateToURLWithDisposition( 240 browser(), test_page, NEW_BACKGROUND_TAB, 241 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 242 243 // Restart and session restore the tabs. 244 content::DOMMessageQueue message_queue; 245 Browser* restored = QuitBrowserAndRestore(browser(), 3); 246 for (int i = 0; i < 2; ++i) { 247 std::string message; 248 EXPECT_TRUE(message_queue.WaitForMessage(&message)); 249 EXPECT_EQ("\"READY\"", message); 250 } 251 252 // There should be 3 restored tabs in the new browser. 253 TabStripModel* tab_strip_model = restored->tab_strip_model(); 254 const int tabs = tab_strip_model->count(); 255 ASSERT_EQ(3, tabs); 256 257 // The middle tab only should have visible disposition. 258 for (int i = 0; i < tabs; ++i) { 259 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i); 260 std::string document_visibility_state; 261 const char kGetStateJS[] = "window.domAutomationController.send(" 262 "window.document.visibilityState);"; 263 EXPECT_TRUE(content::ExecuteScriptAndExtractString( 264 contents, kGetStateJS, &document_visibility_state)); 265 if (i == 1) { 266 EXPECT_EQ("visible", document_visibility_state); 267 } else { 268 EXPECT_EQ("hidden", document_visibility_state); 269 } 270 } 271 } 272 273 #if defined(OS_CHROMEOS) 274 // Verify that session restore does not occur when a user opens a browser window 275 // when no other browser windows are open on ChromeOS. 276 // TODO(pkotwicz): Add test which doesn't open incognito browser once 277 // disable-zero-browsers-open-for-tests is removed. 278 // (http://crbug.com/119175) 279 // TODO(pkotwicz): Mac should have the behavior outlined by this test. It should 280 // not do session restore if an incognito window is already open. 281 // (http://crbug.com/120927) 282 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) { 283 GURL url(ui_test_utils::GetTestUrl( 284 base::FilePath(base::FilePath::kCurrentDirectory), 285 base::FilePath(FILE_PATH_LITERAL("title1.html")))); 286 287 // Add a single tab. 288 ui_test_utils::NavigateToURL(browser(), url); 289 290 Browser* incognito_browser = CreateIncognitoBrowser(); 291 chrome::AddTabAt(incognito_browser, GURL(), -1, true); 292 incognito_browser->window()->Show(); 293 294 // Close the normal browser. After this we only have the incognito window 295 // open. 296 CloseBrowserSynchronously(browser()); 297 298 // Create a new window, which should open NTP. 299 ui_test_utils::BrowserAddedObserver browser_added_observer; 300 chrome::NewWindow(incognito_browser); 301 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser(); 302 303 ASSERT_TRUE(new_browser); 304 EXPECT_EQ(1, new_browser->tab_strip_model()->count()); 305 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), 306 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL()); 307 } 308 309 // Test that maximized applications get restored maximized. 310 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MaximizedApps) { 311 const char* app_name = "TestApp"; 312 Browser* app_browser = CreateBrowserForApp(app_name, browser()->profile()); 313 app_browser->window()->Maximize(); 314 app_browser->window()->Show(); 315 EXPECT_TRUE(app_browser->window()->IsMaximized()); 316 EXPECT_TRUE(app_browser->is_app()); 317 EXPECT_TRUE(app_browser->is_type_popup()); 318 319 // Close the normal browser. After this we only have the app_browser window. 320 CloseBrowserSynchronously(browser()); 321 322 // Create a new window, which should open NTP. 323 ui_test_utils::BrowserAddedObserver browser_added_observer; 324 chrome::NewWindow(app_browser); 325 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser(); 326 327 ASSERT_TRUE(new_browser); 328 EXPECT_TRUE(app_browser->window()->IsMaximized()); 329 EXPECT_TRUE(app_browser->is_app()); 330 EXPECT_TRUE(app_browser->is_type_popup()); 331 } 332 #endif // OS_CHROMEOS 333 334 #if !defined(OS_CHROMEOS) 335 // This test does not apply to ChromeOS as it does not do session restore when 336 // a new window is opened. 337 338 #if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) 339 // Crashes on Linux Views: http://crbug.com/39476 340 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \ 341 DISABLED_RestoreOnNewWindowWithNoTabbedBrowsers 342 #else 343 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \ 344 RestoreOnNewWindowWithNoTabbedBrowsers 345 #endif 346 347 // Makes sure when session restore is triggered in the same process we don't end 348 // up with an extra tab. 349 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, 350 MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers) { 351 const base::FilePath::CharType* kTitle1File = 352 FILE_PATH_LITERAL("title1.html"); 353 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 354 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File))); 355 ui_test_utils::NavigateToURL(browser(), url); 356 357 // Turn on session restore. 358 SessionStartupPref::SetStartupPref( 359 browser()->profile(), 360 SessionStartupPref(SessionStartupPref::LAST)); 361 362 // Create a new popup. 363 Profile* profile = browser()->profile(); 364 Browser* popup = 365 new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, 366 browser()->host_desktop_type())); 367 popup->window()->Show(); 368 369 // Close the browser. 370 CloseBrowserSynchronously(browser()); 371 372 // Create a new window, which should trigger session restore. 373 ui_test_utils::BrowserAddedObserver observer; 374 chrome::NewWindow(popup); 375 Browser* new_browser = observer.WaitForSingleNewBrowser(); 376 377 ASSERT_TRUE(new_browser != NULL); 378 379 // The browser should only have one tab. 380 ASSERT_EQ(1, new_browser->tab_strip_model()->count()); 381 382 // And the first url should be url. 383 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL()); 384 } 385 #endif // !OS_CHROMEOS 386 387 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreIndividualTabFromWindow) { 388 GURL url1(ui_test_utils::GetTestUrl( 389 base::FilePath(base::FilePath::kCurrentDirectory), 390 base::FilePath(FILE_PATH_LITERAL("title1.html")))); 391 // Any page that will yield a 200 status code will work here. 392 GURL url2("about:version"); 393 GURL url3(ui_test_utils::GetTestUrl( 394 base::FilePath(base::FilePath::kCurrentDirectory), 395 base::FilePath(FILE_PATH_LITERAL("title3.html")))); 396 397 // Add and navigate three tabs. 398 ui_test_utils::NavigateToURL(browser(), url1); 399 { 400 content::WindowedNotificationObserver observer( 401 content::NOTIFICATION_LOAD_STOP, 402 content::NotificationService::AllSources()); 403 chrome::AddSelectedTabWithURL(browser(), url2, 404 ui::PAGE_TRANSITION_LINK); 405 observer.Wait(); 406 } 407 { 408 content::WindowedNotificationObserver observer( 409 content::NOTIFICATION_LOAD_STOP, 410 content::NotificationService::AllSources()); 411 chrome::AddSelectedTabWithURL(browser(), url3, 412 ui::PAGE_TRANSITION_LINK); 413 observer.Wait(); 414 } 415 416 TabRestoreService* service = 417 TabRestoreServiceFactory::GetForProfile(browser()->profile()); 418 service->ClearEntries(); 419 420 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type(); 421 422 browser()->window()->Close(); 423 424 // Expect a window with three tabs. 425 ASSERT_EQ(1U, service->entries().size()); 426 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type); 427 const TabRestoreService::Window* window = 428 static_cast<TabRestoreService::Window*>(service->entries().front()); 429 EXPECT_EQ(3U, window->tabs.size()); 430 431 // Find the SessionID for entry2. Since the session service was destroyed, 432 // there is no guarantee that the SessionID for the tab has remained the same. 433 base::Time timestamp; 434 int http_status_code = 0; 435 for (std::vector<TabRestoreService::Tab>::const_iterator it = 436 window->tabs.begin(); it != window->tabs.end(); ++it) { 437 const TabRestoreService::Tab& tab = *it; 438 // If this tab held url2, then restore this single tab. 439 if (tab.navigations[0].virtual_url() == url2) { 440 timestamp = tab.navigations[0].timestamp(); 441 http_status_code = tab.navigations[0].http_status_code(); 442 std::vector<content::WebContents*> content = 443 service->RestoreEntryById(NULL, tab.id, host_desktop_type, UNKNOWN); 444 ASSERT_EQ(1U, content.size()); 445 ASSERT_TRUE(content[0]); 446 EXPECT_EQ(url2, content[0]->GetURL()); 447 break; 448 } 449 } 450 EXPECT_FALSE(timestamp.is_null()); 451 EXPECT_EQ(200, http_status_code); 452 453 // Make sure that the restored tab is removed from the service. 454 ASSERT_EQ(1U, service->entries().size()); 455 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type); 456 window = static_cast<TabRestoreService::Window*>(service->entries().front()); 457 EXPECT_EQ(2U, window->tabs.size()); 458 459 // Make sure that the restored tab was restored with the correct 460 // timestamp and status code. 461 const content::WebContents* contents = 462 browser()->tab_strip_model()->GetActiveWebContents(); 463 ASSERT_TRUE(contents); 464 const content::NavigationEntry* entry = 465 contents->GetController().GetActiveEntry(); 466 ASSERT_TRUE(entry); 467 EXPECT_EQ(timestamp, entry->GetTimestamp()); 468 EXPECT_EQ(http_status_code, entry->GetHttpStatusCode()); 469 } 470 471 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) { 472 GURL url(ui_test_utils::GetTestUrl( 473 base::FilePath(base::FilePath::kCurrentDirectory), 474 base::FilePath(FILE_PATH_LITERAL("title1.html")))); 475 476 // Add a single tab. 477 ui_test_utils::NavigateToURL(browser(), url); 478 479 TabRestoreService* service = 480 TabRestoreServiceFactory::GetForProfile(browser()->profile()); 481 service->ClearEntries(); 482 EXPECT_EQ(0U, service->entries().size()); 483 484 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type(); 485 486 // Close the window. 487 browser()->window()->Close(); 488 489 // Expect the window to be converted to a tab by the TRS. 490 EXPECT_EQ(1U, service->entries().size()); 491 ASSERT_EQ(TabRestoreService::TAB, service->entries().front()->type); 492 const TabRestoreService::Tab* tab = 493 static_cast<TabRestoreService::Tab*>(service->entries().front()); 494 495 // Restore the tab. 496 std::vector<content::WebContents*> content = 497 service->RestoreEntryById(NULL, tab->id, host_desktop_type, UNKNOWN); 498 ASSERT_EQ(1U, content.size()); 499 ASSERT_TRUE(content[0]); 500 EXPECT_EQ(url, content[0]->GetURL()); 501 502 // Make sure the restore was successful. 503 EXPECT_EQ(0U, service->entries().size()); 504 } 505 506 #if !defined(OS_CHROMEOS) 507 // This test does not apply to ChromeOS as ChromeOS does not do session 508 // restore when a new window is open. 509 510 // Verifies we remember the last browser window when closing the last 511 // non-incognito window while an incognito window is open. 512 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) { 513 GURL url(ui_test_utils::GetTestUrl( 514 base::FilePath(base::FilePath::kCurrentDirectory), 515 base::FilePath(FILE_PATH_LITERAL("title1.html")))); 516 517 // Add a single tab. 518 ui_test_utils::NavigateToURL(browser(), url); 519 520 // Create a new incognito window. 521 Browser* incognito_browser = CreateIncognitoBrowser(); 522 chrome::AddTabAt(incognito_browser, GURL(), -1, true); 523 incognito_browser->window()->Show(); 524 525 // Close the normal browser. After this we only have the incognito window 526 // open. 527 CloseBrowserSynchronously(browser()); 528 529 // Create a new window, which should trigger session restore. 530 ui_test_utils::BrowserAddedObserver browser_added_observer; 531 chrome::NewWindow(incognito_browser); 532 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser(); 533 534 // The first tab should have 'url' as its url. 535 ASSERT_TRUE(new_browser); 536 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL()); 537 } 538 #endif // !OS_CHROMEOS 539 540 namespace { 541 542 // Verifies that the given NavigationController has exactly two 543 // entries that correspond to the given URLs and that all but the last 544 // entry have null timestamps. 545 void VerifyNavigationEntries( 546 const content::NavigationController& controller, 547 GURL url1, GURL url2) { 548 ASSERT_EQ(2, controller.GetEntryCount()); 549 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 550 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); 551 EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL()); 552 EXPECT_TRUE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null()); 553 EXPECT_FALSE(controller.GetEntryAtIndex(1)->GetTimestamp().is_null()); 554 } 555 556 } // namespace 557 558 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) { 559 GURL url1("http://google.com"); 560 GURL url2("http://google2.com"); 561 SerializedNavigationEntry nav1 = 562 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one"); 563 SerializedNavigationEntry nav2 = 564 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two"); 565 566 // Set up the restore data. 567 sync_pb::SessionTab sync_data; 568 sync_data.set_tab_visual_index(0); 569 sync_data.set_current_navigation_index(1); 570 sync_data.set_pinned(false); 571 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData()); 572 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData()); 573 574 SessionTab tab; 575 tab.SetFromSyncData(sync_data, base::Time::Now()); 576 EXPECT_EQ(2U, tab.navigations.size()); 577 for (size_t i = 0; i < tab.navigations.size(); ++i) 578 EXPECT_TRUE(tab.navigations[i].timestamp().is_null()); 579 580 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 581 582 // Restore in the current tab. 583 content::WebContents* tab_content = NULL; 584 { 585 content::WindowedNotificationObserver observer( 586 content::NOTIFICATION_LOAD_STOP, 587 content::NotificationService::AllSources()); 588 tab_content = SessionRestore::RestoreForeignSessionTab( 589 browser()->tab_strip_model()->GetActiveWebContents(), tab, CURRENT_TAB); 590 observer.Wait(); 591 } 592 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 593 content::WebContents* web_contents = 594 browser()->tab_strip_model()->GetWebContentsAt(0); 595 VerifyNavigationEntries(web_contents->GetController(), url1, url2); 596 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty()); 597 ASSERT_TRUE(tab_content); 598 ASSERT_EQ(url2, tab_content->GetURL()); 599 600 // Restore in a new tab. 601 tab_content = NULL; 602 { 603 content::WindowedNotificationObserver observer( 604 content::NOTIFICATION_LOAD_STOP, 605 content::NotificationService::AllSources()); 606 tab_content = SessionRestore::RestoreForeignSessionTab( 607 browser()->tab_strip_model()->GetActiveWebContents(), 608 tab, NEW_BACKGROUND_TAB); 609 observer.Wait(); 610 } 611 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 612 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 613 web_contents = browser()->tab_strip_model()->GetWebContentsAt(1); 614 VerifyNavigationEntries(web_contents->GetController(), url1, url2); 615 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty()); 616 ASSERT_TRUE(tab_content); 617 ASSERT_EQ(url2, tab_content->GetURL()); 618 619 // Restore in a new window. 620 Browser* new_browser = NULL; 621 tab_content = NULL; 622 { 623 ui_test_utils::BrowserAddedObserver browser_observer; 624 content::WindowedNotificationObserver observer( 625 content::NOTIFICATION_LOAD_STOP, 626 content::NotificationService::AllSources()); 627 tab_content = SessionRestore::RestoreForeignSessionTab( 628 browser()->tab_strip_model()->GetActiveWebContents(), tab, NEW_WINDOW); 629 new_browser = browser_observer.WaitForSingleNewBrowser(); 630 observer.Wait(); 631 } 632 633 ASSERT_EQ(1, new_browser->tab_strip_model()->count()); 634 web_contents = new_browser->tab_strip_model()->GetWebContentsAt(0); 635 VerifyNavigationEntries(web_contents->GetController(), url1, url2); 636 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty()); 637 ASSERT_TRUE(tab_content); 638 ASSERT_EQ(url2, tab_content->GetURL()); 639 } 640 641 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) { 642 Profile* profile = browser()->profile(); 643 644 GURL url1("http://google.com"); 645 GURL url2("http://google2.com"); 646 SerializedNavigationEntry nav1 = 647 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one"); 648 SerializedNavigationEntry nav2 = 649 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two"); 650 SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav2); 651 652 // Set up the restore data -- one window with two tabs. 653 std::vector<const SessionWindow*> session; 654 SessionWindow window; 655 SessionTab tab1; 656 { 657 sync_pb::SessionTab sync_data; 658 sync_data.set_tab_visual_index(0); 659 sync_data.set_current_navigation_index(0); 660 sync_data.set_pinned(true); 661 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData()); 662 tab1.SetFromSyncData(sync_data, base::Time::Now()); 663 } 664 window.tabs.push_back(&tab1); 665 666 SessionTab tab2; 667 { 668 sync_pb::SessionTab sync_data; 669 sync_data.set_tab_visual_index(1); 670 sync_data.set_current_navigation_index(0); 671 sync_data.set_pinned(false); 672 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData()); 673 tab2.SetFromSyncData(sync_data, base::Time::Now()); 674 } 675 window.tabs.push_back(&tab2); 676 677 // Leave tab3 empty. Should have no effect on restored session, but simulates 678 // partially complete foreign session data. 679 SessionTab tab3; 680 window.tabs.push_back(&tab3); 681 682 session.push_back(static_cast<const SessionWindow*>(&window)); 683 ui_test_utils::BrowserAddedObserver window_observer; 684 std::vector<Browser*> browsers = 685 SessionRestore::RestoreForeignSessionWindows( 686 profile, browser()->host_desktop_type(), session.begin(), 687 session.end()); 688 Browser* new_browser = window_observer.WaitForSingleNewBrowser(); 689 ASSERT_TRUE(new_browser); 690 ASSERT_EQ(2u, active_browser_list_->size()); 691 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 692 693 ASSERT_EQ(1u, browsers.size()); 694 ASSERT_TRUE(browsers[0]); 695 ASSERT_EQ(2, browsers[0]->tab_strip_model()->count()); 696 697 content::WebContents* web_contents_1 = 698 new_browser->tab_strip_model()->GetWebContentsAt(0); 699 content::WebContents* web_contents_2 = 700 new_browser->tab_strip_model()->GetWebContentsAt(1); 701 ASSERT_EQ(url1, web_contents_1->GetURL()); 702 ASSERT_EQ(url2, web_contents_2->GetURL()); 703 704 // Check user agent override state. 705 ASSERT_TRUE(web_contents_1->GetUserAgentOverride().empty()); 706 ASSERT_TRUE(web_contents_2->GetUserAgentOverride().empty()); 707 708 content::NavigationEntry* entry = 709 web_contents_1->GetController().GetActiveEntry(); 710 ASSERT_TRUE(entry); 711 ASSERT_FALSE(entry->GetIsOverridingUserAgent()); 712 713 entry = web_contents_2->GetController().GetActiveEntry(); 714 ASSERT_TRUE(entry); 715 ASSERT_FALSE(entry->GetIsOverridingUserAgent()); 716 717 // The SessionWindow destructor deletes the tabs, so we have to clear them 718 // here to avoid a crash. 719 window.tabs.clear(); 720 } 721 722 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) { 723 ui_test_utils::NavigateToURL(browser(), url1_); 724 ui_test_utils::NavigateToURL(browser(), url2_); 725 726 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 727 ASSERT_EQ(1u, active_browser_list_->size()); 728 ASSERT_EQ(url2_, 729 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 730 GoBack(new_browser); 731 ASSERT_EQ(url1_, 732 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 733 } 734 735 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) { 736 const GURL webui_url("chrome://omnibox"); 737 ui_test_utils::NavigateToURL(browser(), webui_url); 738 const content::WebContents* old_tab = 739 browser()->tab_strip_model()->GetActiveWebContents(); 740 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI, 741 old_tab->GetRenderViewHost()->GetEnabledBindings()); 742 743 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 744 ASSERT_EQ(1u, active_browser_list_->size()); 745 const content::WebContents* new_tab = 746 new_browser->tab_strip_model()->GetActiveWebContents(); 747 EXPECT_EQ(webui_url, new_tab->GetURL()); 748 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI, 749 new_tab->GetRenderViewHost()->GetEnabledBindings()); 750 } 751 752 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUISettings) { 753 const GURL webui_url("chrome://settings"); 754 ui_test_utils::NavigateToURL(browser(), webui_url); 755 const content::WebContents* old_tab = 756 browser()->tab_strip_model()->GetActiveWebContents(); 757 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI, 758 old_tab->GetRenderViewHost()->GetEnabledBindings()); 759 760 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 761 ASSERT_EQ(1u, active_browser_list_->size()); 762 const content::WebContents* new_tab = 763 new_browser->tab_strip_model()->GetActiveWebContents(); 764 EXPECT_EQ(webui_url, new_tab->GetURL()); 765 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI, 766 new_tab->GetRenderViewHost()->GetEnabledBindings()); 767 } 768 769 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) { 770 ui_test_utils::NavigateToURL(browser(), url1_); 771 ui_test_utils::NavigateToURL(browser(), url2_); 772 ui_test_utils::NavigateToURL(browser(), url3_); 773 774 GoBack(browser()); 775 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 776 ASSERT_EQ(1u, active_browser_list_->size()); 777 ASSERT_EQ(url2_, 778 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 779 GoForward(new_browser); 780 ASSERT_EQ(url3_, 781 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 782 GoBack(new_browser); 783 ASSERT_EQ(url2_, 784 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 785 786 // Test renderer-initiated back/forward as well. 787 GURL go_back_url("javascript:history.back();"); 788 ui_test_utils::NavigateToURL(new_browser, go_back_url); 789 ASSERT_EQ(url1_, 790 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 791 } 792 793 // Tests that the SiteInstances used for entries in a restored tab's history 794 // are given appropriate max page IDs, so that going back to a restored 795 // cross-site page and then forward again works. (Bug 1204135) 796 // This test fails. See http://crbug.com/237497. 797 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, 798 DISABLED_RestoresCrossSiteForwardAndBackwardNavs) { 799 ASSERT_TRUE(test_server()->Start()); 800 801 GURL cross_site_url(test_server()->GetURL("files/title2.html")); 802 803 // Visit URLs on different sites. 804 ui_test_utils::NavigateToURL(browser(), url1_); 805 ui_test_utils::NavigateToURL(browser(), cross_site_url); 806 ui_test_utils::NavigateToURL(browser(), url2_); 807 808 GoBack(browser()); 809 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 810 ASSERT_EQ(1u, active_browser_list_->size()); 811 ASSERT_EQ(1, new_browser->tab_strip_model()->count()); 812 813 // Check that back and forward work as expected. 814 ASSERT_EQ(cross_site_url, 815 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 816 817 GoBack(new_browser); 818 ASSERT_EQ(url1_, 819 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 820 821 GoForward(new_browser); 822 ASSERT_EQ(cross_site_url, 823 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 824 825 // Test renderer-initiated back/forward as well. 826 GURL go_forward_url("javascript:history.forward();"); 827 ui_test_utils::NavigateToURL(new_browser, go_forward_url); 828 ASSERT_EQ(url2_, 829 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 830 } 831 832 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) { 833 ui_test_utils::NavigateToURL(browser(), url1_); 834 835 ui_test_utils::NavigateToURLWithDisposition( 836 browser(), url2_, NEW_FOREGROUND_TAB, 837 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 838 839 Browser* new_browser = QuitBrowserAndRestore(browser(), 2); 840 841 ASSERT_EQ(1u, active_browser_list_->size()); 842 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 843 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index()); 844 ASSERT_EQ(url2_, 845 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 846 847 ASSERT_EQ(url1_, 848 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL()); 849 } 850 851 // Creates two tabs, closes one, quits and makes sure only one tab is restored. 852 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) { 853 ui_test_utils::NavigateToURL(browser(), url1_); 854 855 ui_test_utils::NavigateToURLWithDisposition( 856 browser(), url2_, NEW_FOREGROUND_TAB, 857 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 858 chrome::CloseTab(browser()); 859 860 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 861 862 AssertOneWindowWithOneTab(new_browser); 863 ASSERT_EQ(url1_, 864 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 865 } 866 867 // Ensures active tab properly restored when tabs before it closed. 868 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtClose) { 869 ui_test_utils::NavigateToURL(browser(), url1_); 870 ui_test_utils::NavigateToURLWithDisposition( 871 browser(), url2_, NEW_FOREGROUND_TAB, 872 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 873 ui_test_utils::NavigateToURLWithDisposition( 874 browser(), url3_, NEW_BACKGROUND_TAB, 875 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 876 877 browser()->tab_strip_model()->CloseWebContentsAt( 878 0, 879 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); 880 881 Browser* new_browser = QuitBrowserAndRestore(browser(), 2); 882 883 ASSERT_EQ(url2_, 884 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 885 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 0); 886 } 887 888 // Ensures active tab properly restored when tabs are inserted before it . 889 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtInsert) { 890 ui_test_utils::NavigateToURL(browser(), url1_); 891 ui_test_utils::NavigateToURLWithDisposition( 892 browser(), url2_, NEW_BACKGROUND_TAB, 893 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 894 895 chrome::NavigateParams navigate_params(browser(), url3_, 896 ui::PAGE_TRANSITION_TYPED); 897 navigate_params.tabstrip_index = 0; 898 navigate_params.disposition = NEW_BACKGROUND_TAB; 899 ui_test_utils::NavigateToURL(&navigate_params); 900 901 Browser* new_browser = QuitBrowserAndRestore(browser(), 3); 902 903 ASSERT_EQ(url1_, 904 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 905 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1); 906 } 907 908 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX) 909 // This test doesn't apply to the Mac version; see GetCommandLineForRelaunch 910 // for details. It was disabled for a long time so might never have worked on 911 // ChromeOS. 912 913 // Launches an app window, closes tabbed browser, launches and makes sure 914 // we restore the tabbed browser url. 915 // If this test flakes, use http://crbug.com/29110 916 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, 917 RestoreAfterClosingTabbedBrowserWithAppAndLaunching) { 918 #if defined(OS_WIN) && defined(USE_ASH) 919 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 920 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 921 return; 922 #endif 923 924 ui_test_utils::NavigateToURL(browser(), url1_); 925 926 // Launch an app. 927 CommandLine app_launch_arguments = GetCommandLineForRelaunch(); 928 app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec()); 929 930 ui_test_utils::BrowserAddedObserver window_observer; 931 932 base::LaunchProcess(app_launch_arguments, base::LaunchOptionsForTest(), NULL); 933 934 Browser* app_window = window_observer.WaitForSingleNewBrowser(); 935 ASSERT_EQ(2u, active_browser_list_->size()); 936 937 // Close the first window. The only window left is the App window. 938 CloseBrowserSynchronously(browser()); 939 940 // Restore the session, which should bring back the first window with url1_. 941 Browser* new_browser = QuitBrowserAndRestore(app_window, 1); 942 943 AssertOneWindowWithOneTab(new_browser); 944 945 ASSERT_EQ(url1_, 946 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 947 } 948 949 #endif // !defined(OS_CHROMEOS) && !defined(OS_MACOSX) 950 951 // Creates two windows, closes one, restores, make sure only one window open. 952 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) { 953 ui_test_utils::NavigateToURL(browser(), url1_); 954 955 // Open a second window. 956 ui_test_utils::NavigateToURLWithDisposition( 957 browser(), 958 GURL(url::kAboutBlankURL), 959 NEW_WINDOW, 960 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); 961 962 ASSERT_EQ(2u, active_browser_list_->size()); 963 964 // Close it. 965 Browser* new_window = active_browser_list_->get(1); 966 CloseBrowserSynchronously(new_window); 967 968 // Restart and make sure we have only one window with one tab and the url 969 // is url1_. 970 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 971 972 AssertOneWindowWithOneTab(new_browser); 973 974 ASSERT_EQ(url1_, 975 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 976 } 977 978 // Make sure after a restore the number of processes matches that of the number 979 // of processes running before the restore. This creates a new tab so that 980 // we should have two new tabs running. (This test will pass in both 981 // process-per-site and process-per-site-instance, because we treat the new tab 982 // as a special case in process-per-site-instance so that it only ever uses one 983 // process.) 984 // 985 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022 986 // Unfortunately, the fix at http://codereview.chromium.org/6546078 987 // breaks NTP background image refreshing, so ThemeSource had to revert to 988 // replacing the existing data source. 989 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) { 990 // Create two new tabs. 991 ui_test_utils::NavigateToURLWithDisposition( 992 browser(), 993 GURL(url::kAboutBlankURL), 994 NEW_FOREGROUND_TAB, 995 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 996 ui_test_utils::NavigateToURLWithDisposition( 997 browser(), 998 GURL(url::kAboutBlankURL), 999 NEW_FOREGROUND_TAB, 1000 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 1001 1002 int expected_process_count = RenderProcessHostCount(); 1003 1004 // Restart. 1005 Browser* new_browser = QuitBrowserAndRestore(browser(), 3); 1006 1007 ASSERT_EQ(3, new_browser->tab_strip_model()->count()); 1008 1009 ASSERT_EQ(expected_process_count, RenderProcessHostCount()); 1010 } 1011 1012 // Test that changing the user agent override will persist it to disk. 1013 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, PersistAndRestoreUserAgentOverride) { 1014 // Create a tab with an overridden user agent. 1015 ui_test_utils::NavigateToURL(browser(), url1_); 1016 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 1017 browser()->tab_strip_model()->GetWebContentsAt(0)-> 1018 SetUserAgentOverride("override"); 1019 1020 // Create a tab without an overridden user agent. 1021 ui_test_utils::NavigateToURLWithDisposition( 1022 browser(), url2_, NEW_FOREGROUND_TAB, 1023 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 1024 ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); 1025 1026 // Kill the original browser then open a new one to trigger a restore. 1027 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 1028 ASSERT_EQ(1u, active_browser_list_->size()); 1029 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 1030 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index()); 1031 1032 // Confirm that the user agent overrides are properly set. 1033 EXPECT_EQ("override", 1034 new_browser->tab_strip_model()->GetWebContentsAt(0)-> 1035 GetUserAgentOverride()); 1036 EXPECT_EQ("", 1037 new_browser->tab_strip_model()->GetWebContentsAt(1)-> 1038 GetUserAgentOverride()); 1039 } 1040 1041 // Regression test for crbug.com/125958. When restoring a pinned selected tab in 1042 // a setting where there are existing tabs, the selected index computation was 1043 // wrong, leading to the wrong tab getting selected, DCHECKs firing, and the 1044 // pinned tab not getting loaded. 1045 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestorePinnedSelectedTab) { 1046 // Create a pinned tab. 1047 ui_test_utils::NavigateToURL(browser(), url1_); 1048 browser()->tab_strip_model()->SetTabPinned(0, true); 1049 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 1050 // Create a nonpinned tab. 1051 ui_test_utils::NavigateToURLWithDisposition( 1052 browser(), url2_, NEW_FOREGROUND_TAB, 1053 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 1054 ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); 1055 // Select the pinned tab. 1056 browser()->tab_strip_model()->ActivateTabAt(0, true); 1057 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 1058 Profile* profile = browser()->profile(); 1059 1060 // This will also initiate a session restore, but we're not interested in it. 1061 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 1062 ASSERT_EQ(1u, active_browser_list_->size()); 1063 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 1064 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index()); 1065 // Close the pinned tab. 1066 chrome::CloseTab(new_browser); 1067 ASSERT_EQ(1, new_browser->tab_strip_model()->count()); 1068 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index()); 1069 // Use the existing tab to navigate away, so that we can verify it was really 1070 // clobbered. 1071 ui_test_utils::NavigateToURL(new_browser, url3_); 1072 1073 // Restore the session again, clobbering the existing tab. 1074 SessionRestore::RestoreSession( 1075 profile, new_browser, 1076 new_browser->host_desktop_type(), 1077 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS, 1078 std::vector<GURL>()); 1079 1080 // The pinned tab is the selected tab. 1081 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 1082 EXPECT_EQ(0, new_browser->tab_strip_model()->active_index()); 1083 EXPECT_EQ(url1_, 1084 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 1085 EXPECT_EQ(url2_, 1086 new_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL()); 1087 } 1088 1089 // Regression test for crbug.com/240156. When restoring tabs with a navigation, 1090 // the navigation should take active tab focus. 1091 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWithNavigateSelectedTab) { 1092 // Create 2 tabs. 1093 ui_test_utils::NavigateToURL(browser(), url1_); 1094 ui_test_utils::NavigateToURLWithDisposition( 1095 browser(), url2_, NEW_FOREGROUND_TAB, 1096 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 1097 1098 // Restore the session by calling chrome::Navigate(). 1099 Browser* new_browser = QuitBrowserAndRestoreWithURL(browser(), 3, url3_); 1100 ASSERT_EQ(1u, active_browser_list_->size()); 1101 ASSERT_EQ(3, new_browser->tab_strip_model()->count()); 1102 // Navigated url should be the active tab. 1103 ASSERT_EQ(url3_, 1104 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 1105 } 1106 1107 // Do a clobber restore from the new tab page. This test follows the code path 1108 // of a crash followed by the user clicking restore from the new tab page. 1109 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClobberRestoreTest) { 1110 // Create 2 tabs. 1111 ui_test_utils::NavigateToURL(browser(), url1_); 1112 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 1113 ui_test_utils::NavigateToURLWithDisposition( 1114 browser(), url2_, NEW_FOREGROUND_TAB, 1115 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 1116 ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); 1117 Profile* profile = browser()->profile(); 1118 1119 // This will also initiate a session restore, but we're not interested in it. 1120 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 1121 ASSERT_EQ(1u, active_browser_list_->size()); 1122 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 1123 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index()); 1124 // Close the first tab. 1125 chrome::CloseTab(new_browser); 1126 ASSERT_EQ(1, new_browser->tab_strip_model()->count()); 1127 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index()); 1128 // Use the existing tab to navigate to the NTP. 1129 ui_test_utils::NavigateToURL(new_browser, GURL(chrome::kChromeUINewTabURL)); 1130 1131 // Restore the session again, clobbering the existing tab. 1132 SessionRestore::RestoreSession( 1133 profile, new_browser, 1134 new_browser->host_desktop_type(), 1135 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS, 1136 std::vector<GURL>()); 1137 1138 // 2 tabs should have been restored, with the existing tab clobbered, giving 1139 // us a total of 2 tabs. 1140 ASSERT_EQ(2, new_browser->tab_strip_model()->count()); 1141 EXPECT_EQ(1, new_browser->tab_strip_model()->active_index()); 1142 EXPECT_EQ(url1_, 1143 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL()); 1144 EXPECT_EQ(url2_, 1145 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 1146 } 1147 1148 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) { 1149 ui_test_utils::NavigateToURL(browser(), url1_); 1150 content::NavigationController* controller = 1151 &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); 1152 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace()); 1153 std::string session_storage_persistent_id = 1154 controller->GetDefaultSessionStorageNamespace()->persistent_id(); 1155 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 1156 ASSERT_EQ(1u, active_browser_list_->size()); 1157 ASSERT_EQ(url1_, 1158 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); 1159 content::NavigationController* new_controller = 1160 &new_browser->tab_strip_model()->GetActiveWebContents()->GetController(); 1161 ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace()); 1162 std::string restored_session_storage_persistent_id = 1163 new_controller->GetDefaultSessionStorageNamespace()->persistent_id(); 1164 EXPECT_EQ(session_storage_persistent_id, 1165 restored_session_storage_persistent_id); 1166 } 1167 1168 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) { 1169 // Simulate what prerendering does: create a new WebContents with the same 1170 // SessionStorageNamespace as an existing tab, then replace the tab with it. 1171 { 1172 content::NavigationController* controller = 1173 &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); 1174 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace()); 1175 1176 content::SessionStorageNamespaceMap session_storage_namespace_map; 1177 session_storage_namespace_map[std::string()] = 1178 controller->GetDefaultSessionStorageNamespace(); 1179 scoped_ptr<content::WebContents> web_contents( 1180 content::WebContents::CreateWithSessionStorage( 1181 content::WebContents::CreateParams(browser()->profile()), 1182 session_storage_namespace_map)); 1183 1184 TabStripModel* tab_strip_model = browser()->tab_strip_model(); 1185 scoped_ptr<content::WebContents> old_web_contents( 1186 tab_strip_model->ReplaceWebContentsAt( 1187 tab_strip_model->active_index(), web_contents.release())); 1188 // Navigate with the new tab. 1189 ui_test_utils::NavigateToURL(browser(), url2_); 1190 // old_web_contents goes out of scope. 1191 } 1192 1193 // Check that the sessionStorage data is going to be persisted. 1194 content::NavigationController* controller = 1195 &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); 1196 EXPECT_TRUE( 1197 controller->GetDefaultSessionStorageNamespace()->should_persist()); 1198 1199 // Quit and restore. Check that no extra tabs were created. 1200 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); 1201 ASSERT_EQ(1u, active_browser_list_->size()); 1202 EXPECT_EQ(1, new_browser->tab_strip_model()->count()); 1203 } 1204