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