Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / chrome / browser / sessions / session_restore_browsertest.cc
blob25c306d05b56fa934e3a47a0ef0d5325b16fc749
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.
5 #include <vector>
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/browser/web_contents_view.h"
46 #include "content/public/common/bindings_policy.h"
47 #include "content/public/common/page_transition_types.h"
48 #include "content/public/test/test_navigation_observer.h"
49 #include "sync/protocol/session_specifics.pb.h"
51 using sessions::SerializedNavigationEntry;
52 using sessions::SerializedNavigationEntryTestHelper;
54 #if defined(OS_MACOSX)
55 #include "base/mac/scoped_nsautorelease_pool.h"
56 #endif
58 #if defined(USE_AURA)
59 #include "ui/aura/window.h"
60 #endif
62 class SessionRestoreTest : public InProcessBrowserTest {
63 public:
64 SessionRestoreTest() : active_browser_list_(NULL) {}
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);
73 #endif
75 virtual void SetUpOnMainThread() OVERRIDE {
76 active_browser_list_ = BrowserList::GetInstance(chrome::GetActiveDesktop());
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();
91 #endif
93 InProcessBrowserTest::SetUpOnMainThread();
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"));
107 return InProcessBrowserTest::SetUpUserDataDirectory();
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();
124 Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) {
125 return QuitBrowserAndRestoreWithURL(browser, expected_tab_count, GURL());
128 Browser* QuitBrowserAndRestoreWithURL(Browser* browser,
129 int expected_tab_count,
130 const GURL& url) {
131 Profile* profile = browser->profile();
133 // Close the browser.
134 g_browser_process->AddRefModule();
135 CloseBrowserSynchronously(browser);
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 content::PAGE_TRANSITION_LINK);
148 chrome::Navigate(&params);
150 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
151 restore_observer.Wait();
152 g_browser_process->ReleaseModule();
154 return new_browser;
157 void GoBack(Browser* browser) {
158 content::TestNavigationObserver observer(
159 browser->tab_strip_model()->GetActiveWebContents());
160 chrome::GoBack(browser, CURRENT_TAB);
161 observer.Wait();
164 void GoForward(Browser* browser) {
165 content::TestNavigationObserver observer(
166 browser->tab_strip_model()->GetActiveWebContents());
167 chrome::GoForward(browser, CURRENT_TAB);
168 observer.Wait();
171 void AssertOneWindowWithOneTab(Browser* browser) {
172 ASSERT_EQ(1u, active_browser_list_->size());
173 ASSERT_EQ(1, browser->tab_strip_model()->count());
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();
185 return count;
188 GURL url1_;
189 GURL url2_;
190 GURL url3_;
192 const BrowserList* active_browser_list_;
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(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB,
203 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
204 ui_test_utils::NavigateToURLWithDisposition(
205 browser(), GURL(content::kAboutBlankURL), NEW_BACKGROUND_TAB,
206 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
208 // Restart and session restore the tabs.
209 Browser* restored = QuitBrowserAndRestore(browser(), 3);
210 TabStripModel* tab_strip_model = restored->tab_strip_model();
211 const int tabs = tab_strip_model->count();
212 ASSERT_EQ(3, tabs);
214 // Check the restored tabs have a root window.
215 for (int i = 0; i < tabs; ++i) {
216 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
217 gfx::NativeView window = contents->GetView()->GetNativeView();
218 bool tab_has_root_window = !!window->GetRootWindow();
219 EXPECT_TRUE(tab_has_root_window);
222 #endif // USE_AURA
224 #if defined(OS_CHROMEOS)
225 // Verify that session restore does not occur when a user opens a browser window
226 // when no other browser windows are open on ChromeOS.
227 // TODO(pkotwicz): Add test which doesn't open incognito browser once
228 // disable-zero-browsers-open-for-tests is removed.
229 // (http://crbug.com/119175)
230 // TODO(pkotwicz): Mac should have the behavior outlined by this test. It should
231 // not do session restore if an incognito window is already open.
232 // (http://crbug.com/120927)
233 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) {
234 GURL url(ui_test_utils::GetTestUrl(
235 base::FilePath(base::FilePath::kCurrentDirectory),
236 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
238 // Add a single tab.
239 ui_test_utils::NavigateToURL(browser(), url);
241 Browser* incognito_browser = CreateIncognitoBrowser();
242 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
243 incognito_browser->window()->Show();
245 // Close the normal browser. After this we only have the incognito window
246 // open.
247 CloseBrowserSynchronously(browser());
249 // Create a new window, which should open NTP.
250 ui_test_utils::BrowserAddedObserver browser_added_observer;
251 chrome::NewWindow(incognito_browser);
252 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
254 ASSERT_TRUE(new_browser);
255 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
256 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
257 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
260 // Test that maximized applications get restored maximized.
261 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MaximizedApps) {
262 const char* app_name = "TestApp";
263 Browser* app_browser = CreateBrowserForApp(app_name, browser()->profile());
264 app_browser->window()->Maximize();
265 app_browser->window()->Show();
266 EXPECT_TRUE(app_browser->window()->IsMaximized());
267 EXPECT_TRUE(app_browser->is_app());
268 EXPECT_TRUE(app_browser->is_type_popup());
270 // Close the normal browser. After this we only have the app_browser window.
271 CloseBrowserSynchronously(browser());
273 // Create a new window, which should open NTP.
274 ui_test_utils::BrowserAddedObserver browser_added_observer;
275 chrome::NewWindow(app_browser);
276 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
278 ASSERT_TRUE(new_browser);
279 EXPECT_TRUE(app_browser->window()->IsMaximized());
280 EXPECT_TRUE(app_browser->is_app());
281 EXPECT_TRUE(app_browser->is_type_popup());
283 #endif // OS_CHROMEOS
285 #if !defined(OS_CHROMEOS)
286 // This test does not apply to ChromeOS as it does not do session restore when
287 // a new window is opened.
289 #if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
290 // Crashes on Linux Views: http://crbug.com/39476
291 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
292 DISABLED_RestoreOnNewWindowWithNoTabbedBrowsers
293 #else
294 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
295 RestoreOnNewWindowWithNoTabbedBrowsers
296 #endif
298 // Makes sure when session restore is triggered in the same process we don't end
299 // up with an extra tab.
300 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
301 MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers) {
302 if (browser_defaults::kRestorePopups)
303 return;
305 const base::FilePath::CharType* kTitle1File =
306 FILE_PATH_LITERAL("title1.html");
307 GURL url(ui_test_utils::GetTestUrl(base::FilePath(
308 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
309 ui_test_utils::NavigateToURL(browser(), url);
311 // Turn on session restore.
312 SessionStartupPref::SetStartupPref(
313 browser()->profile(),
314 SessionStartupPref(SessionStartupPref::LAST));
316 // Create a new popup.
317 Profile* profile = browser()->profile();
318 Browser* popup =
319 new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile,
320 browser()->host_desktop_type()));
321 popup->window()->Show();
323 // Close the browser.
324 CloseBrowserSynchronously(browser());
326 // Create a new window, which should trigger session restore.
327 ui_test_utils::BrowserAddedObserver observer;
328 chrome::NewWindow(popup);
329 Browser* new_browser = observer.WaitForSingleNewBrowser();
331 ASSERT_TRUE(new_browser != NULL);
333 // The browser should only have one tab.
334 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
336 // And the first url should be url.
337 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
339 #endif // !OS_CHROMEOS
341 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreIndividualTabFromWindow) {
342 GURL url1(ui_test_utils::GetTestUrl(
343 base::FilePath(base::FilePath::kCurrentDirectory),
344 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
345 // Any page that will yield a 200 status code will work here.
346 GURL url2("about:version");
347 GURL url3(ui_test_utils::GetTestUrl(
348 base::FilePath(base::FilePath::kCurrentDirectory),
349 base::FilePath(FILE_PATH_LITERAL("title3.html"))));
351 // Add and navigate three tabs.
352 ui_test_utils::NavigateToURL(browser(), url1);
354 content::WindowedNotificationObserver observer(
355 content::NOTIFICATION_LOAD_STOP,
356 content::NotificationService::AllSources());
357 chrome::AddSelectedTabWithURL(browser(), url2,
358 content::PAGE_TRANSITION_LINK);
359 observer.Wait();
362 content::WindowedNotificationObserver observer(
363 content::NOTIFICATION_LOAD_STOP,
364 content::NotificationService::AllSources());
365 chrome::AddSelectedTabWithURL(browser(), url3,
366 content::PAGE_TRANSITION_LINK);
367 observer.Wait();
370 TabRestoreService* service =
371 TabRestoreServiceFactory::GetForProfile(browser()->profile());
372 service->ClearEntries();
374 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
376 browser()->window()->Close();
378 // Expect a window with three tabs.
379 ASSERT_EQ(1U, service->entries().size());
380 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
381 const TabRestoreService::Window* window =
382 static_cast<TabRestoreService::Window*>(service->entries().front());
383 EXPECT_EQ(3U, window->tabs.size());
385 // Find the SessionID for entry2. Since the session service was destroyed,
386 // there is no guarantee that the SessionID for the tab has remained the same.
387 base::Time timestamp;
388 int http_status_code = 0;
389 for (std::vector<TabRestoreService::Tab>::const_iterator it =
390 window->tabs.begin(); it != window->tabs.end(); ++it) {
391 const TabRestoreService::Tab& tab = *it;
392 // If this tab held url2, then restore this single tab.
393 if (tab.navigations[0].virtual_url() == url2) {
394 timestamp = tab.navigations[0].timestamp();
395 http_status_code = tab.navigations[0].http_status_code();
396 std::vector<content::WebContents*> content =
397 service->RestoreEntryById(NULL, tab.id, host_desktop_type, UNKNOWN);
398 ASSERT_EQ(1U, content.size());
399 ASSERT_TRUE(content[0]);
400 EXPECT_EQ(url2, content[0]->GetURL());
401 break;
404 EXPECT_FALSE(timestamp.is_null());
405 EXPECT_EQ(200, http_status_code);
407 // Make sure that the restored tab is removed from the service.
408 ASSERT_EQ(1U, service->entries().size());
409 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
410 window = static_cast<TabRestoreService::Window*>(service->entries().front());
411 EXPECT_EQ(2U, window->tabs.size());
413 // Make sure that the restored tab was restored with the correct
414 // timestamp and status code.
415 const content::WebContents* contents =
416 browser()->tab_strip_model()->GetActiveWebContents();
417 ASSERT_TRUE(contents);
418 const content::NavigationEntry* entry =
419 contents->GetController().GetActiveEntry();
420 ASSERT_TRUE(entry);
421 EXPECT_EQ(timestamp, entry->GetTimestamp());
422 EXPECT_EQ(http_status_code, entry->GetHttpStatusCode());
425 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) {
426 GURL url(ui_test_utils::GetTestUrl(
427 base::FilePath(base::FilePath::kCurrentDirectory),
428 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
430 // Add a single tab.
431 ui_test_utils::NavigateToURL(browser(), url);
433 TabRestoreService* service =
434 TabRestoreServiceFactory::GetForProfile(browser()->profile());
435 service->ClearEntries();
436 EXPECT_EQ(0U, service->entries().size());
438 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
440 // Close the window.
441 browser()->window()->Close();
443 // Expect the window to be converted to a tab by the TRS.
444 EXPECT_EQ(1U, service->entries().size());
445 ASSERT_EQ(TabRestoreService::TAB, service->entries().front()->type);
446 const TabRestoreService::Tab* tab =
447 static_cast<TabRestoreService::Tab*>(service->entries().front());
449 // Restore the tab.
450 std::vector<content::WebContents*> content =
451 service->RestoreEntryById(NULL, tab->id, host_desktop_type, UNKNOWN);
452 ASSERT_EQ(1U, content.size());
453 ASSERT_TRUE(content[0]);
454 EXPECT_EQ(url, content[0]->GetURL());
456 // Make sure the restore was successful.
457 EXPECT_EQ(0U, service->entries().size());
460 #if !defined(OS_CHROMEOS)
461 // This test does not apply to ChromeOS as ChromeOS does not do session
462 // restore when a new window is open.
464 // Verifies we remember the last browser window when closing the last
465 // non-incognito window while an incognito window is open.
466 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) {
467 GURL url(ui_test_utils::GetTestUrl(
468 base::FilePath(base::FilePath::kCurrentDirectory),
469 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
471 // Add a single tab.
472 ui_test_utils::NavigateToURL(browser(), url);
474 // Create a new incognito window.
475 Browser* incognito_browser = CreateIncognitoBrowser();
476 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
477 incognito_browser->window()->Show();
479 // Close the normal browser. After this we only have the incognito window
480 // open.
481 CloseBrowserSynchronously(browser());
483 // Create a new window, which should trigger session restore.
484 ui_test_utils::BrowserAddedObserver browser_added_observer;
485 chrome::NewWindow(incognito_browser);
486 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
488 // The first tab should have 'url' as its url.
489 ASSERT_TRUE(new_browser);
490 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
492 #endif // !OS_CHROMEOS
494 namespace {
496 // Verifies that the given NavigationController has exactly two
497 // entries that correspond to the given URLs and that all but the last
498 // entry have null timestamps.
499 void VerifyNavigationEntries(
500 const content::NavigationController& controller,
501 GURL url1, GURL url2) {
502 ASSERT_EQ(2, controller.GetEntryCount());
503 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
504 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
505 EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL());
506 EXPECT_TRUE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
507 EXPECT_FALSE(controller.GetEntryAtIndex(1)->GetTimestamp().is_null());
510 } // namespace
512 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) {
513 GURL url1("http://google.com");
514 GURL url2("http://google2.com");
515 SerializedNavigationEntry nav1 =
516 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
517 SerializedNavigationEntry nav2 =
518 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
520 // Set up the restore data.
521 sync_pb::SessionTab sync_data;
522 sync_data.set_tab_visual_index(0);
523 sync_data.set_current_navigation_index(1);
524 sync_data.set_pinned(false);
525 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
526 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
528 SessionTab tab;
529 tab.SetFromSyncData(sync_data, base::Time::Now());
530 EXPECT_EQ(2U, tab.navigations.size());
531 for (size_t i = 0; i < tab.navigations.size(); ++i)
532 EXPECT_TRUE(tab.navigations[i].timestamp().is_null());
534 ASSERT_EQ(1, browser()->tab_strip_model()->count());
536 // Restore in the current tab.
537 content::WebContents* tab_content = NULL;
539 content::WindowedNotificationObserver observer(
540 content::NOTIFICATION_LOAD_STOP,
541 content::NotificationService::AllSources());
542 tab_content = SessionRestore::RestoreForeignSessionTab(
543 browser()->tab_strip_model()->GetActiveWebContents(), tab, CURRENT_TAB);
544 observer.Wait();
546 ASSERT_EQ(1, browser()->tab_strip_model()->count());
547 content::WebContents* web_contents =
548 browser()->tab_strip_model()->GetWebContentsAt(0);
549 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
550 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
551 ASSERT_TRUE(tab_content);
552 ASSERT_EQ(url2, tab_content->GetURL());
554 // Restore in a new tab.
555 tab_content = NULL;
557 content::WindowedNotificationObserver observer(
558 content::NOTIFICATION_LOAD_STOP,
559 content::NotificationService::AllSources());
560 tab_content = SessionRestore::RestoreForeignSessionTab(
561 browser()->tab_strip_model()->GetActiveWebContents(),
562 tab, NEW_BACKGROUND_TAB);
563 observer.Wait();
565 ASSERT_EQ(2, browser()->tab_strip_model()->count());
566 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
567 web_contents = browser()->tab_strip_model()->GetWebContentsAt(1);
568 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
569 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
570 ASSERT_TRUE(tab_content);
571 ASSERT_EQ(url2, tab_content->GetURL());
573 // Restore in a new window.
574 Browser* new_browser = NULL;
575 tab_content = NULL;
577 ui_test_utils::BrowserAddedObserver browser_observer;
578 content::WindowedNotificationObserver observer(
579 content::NOTIFICATION_LOAD_STOP,
580 content::NotificationService::AllSources());
581 tab_content = SessionRestore::RestoreForeignSessionTab(
582 browser()->tab_strip_model()->GetActiveWebContents(), tab, NEW_WINDOW);
583 new_browser = browser_observer.WaitForSingleNewBrowser();
584 observer.Wait();
587 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
588 web_contents = new_browser->tab_strip_model()->GetWebContentsAt(0);
589 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
590 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
591 ASSERT_TRUE(tab_content);
592 ASSERT_EQ(url2, tab_content->GetURL());
595 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) {
596 Profile* profile = browser()->profile();
598 GURL url1("http://google.com");
599 GURL url2("http://google2.com");
600 SerializedNavigationEntry nav1 =
601 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
602 SerializedNavigationEntry nav2 =
603 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
604 SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav2);
606 // Set up the restore data -- one window with two tabs.
607 std::vector<const SessionWindow*> session;
608 SessionWindow window;
609 SessionTab tab1;
611 sync_pb::SessionTab sync_data;
612 sync_data.set_tab_visual_index(0);
613 sync_data.set_current_navigation_index(0);
614 sync_data.set_pinned(true);
615 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
616 tab1.SetFromSyncData(sync_data, base::Time::Now());
618 window.tabs.push_back(&tab1);
620 SessionTab tab2;
622 sync_pb::SessionTab sync_data;
623 sync_data.set_tab_visual_index(1);
624 sync_data.set_current_navigation_index(0);
625 sync_data.set_pinned(false);
626 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
627 tab2.SetFromSyncData(sync_data, base::Time::Now());
629 window.tabs.push_back(&tab2);
631 session.push_back(static_cast<const SessionWindow*>(&window));
632 ui_test_utils::BrowserAddedObserver window_observer;
633 std::vector<Browser*> browsers =
634 SessionRestore::RestoreForeignSessionWindows(
635 profile, browser()->host_desktop_type(), session.begin(),
636 session.end());
637 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
638 ASSERT_TRUE(new_browser);
639 ASSERT_EQ(2u, active_browser_list_->size());
640 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
642 ASSERT_EQ(1u, browsers.size());
643 ASSERT_TRUE(browsers[0]);
644 ASSERT_EQ(2, browsers[0]->tab_strip_model()->count());
646 content::WebContents* web_contents_1 =
647 new_browser->tab_strip_model()->GetWebContentsAt(0);
648 content::WebContents* web_contents_2 =
649 new_browser->tab_strip_model()->GetWebContentsAt(1);
650 ASSERT_EQ(url1, web_contents_1->GetURL());
651 ASSERT_EQ(url2, web_contents_2->GetURL());
653 // Check user agent override state.
654 ASSERT_TRUE(web_contents_1->GetUserAgentOverride().empty());
655 ASSERT_TRUE(web_contents_2->GetUserAgentOverride().empty());
657 content::NavigationEntry* entry =
658 web_contents_1->GetController().GetActiveEntry();
659 ASSERT_TRUE(entry);
660 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
662 entry = web_contents_2->GetController().GetActiveEntry();
663 ASSERT_TRUE(entry);
664 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
666 // The SessionWindow destructor deletes the tabs, so we have to clear them
667 // here to avoid a crash.
668 window.tabs.clear();
671 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) {
672 ui_test_utils::NavigateToURL(browser(), url1_);
673 ui_test_utils::NavigateToURL(browser(), url2_);
675 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
676 ASSERT_EQ(1u, active_browser_list_->size());
677 ASSERT_EQ(url2_,
678 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
679 GoBack(new_browser);
680 ASSERT_EQ(url1_,
681 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
684 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) {
685 const GURL webui_url("chrome://omnibox");
686 ui_test_utils::NavigateToURL(browser(), webui_url);
687 const content::WebContents* old_tab =
688 browser()->tab_strip_model()->GetActiveWebContents();
689 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
690 old_tab->GetRenderViewHost()->GetEnabledBindings());
692 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
693 ASSERT_EQ(1u, active_browser_list_->size());
694 const content::WebContents* new_tab =
695 new_browser->tab_strip_model()->GetActiveWebContents();
696 EXPECT_EQ(webui_url, new_tab->GetURL());
697 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
698 new_tab->GetRenderViewHost()->GetEnabledBindings());
701 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUISettings) {
702 const GURL webui_url("chrome://settings");
703 ui_test_utils::NavigateToURL(browser(), webui_url);
704 const content::WebContents* old_tab =
705 browser()->tab_strip_model()->GetActiveWebContents();
706 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
707 old_tab->GetRenderViewHost()->GetEnabledBindings());
709 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
710 ASSERT_EQ(1u, active_browser_list_->size());
711 const content::WebContents* new_tab =
712 new_browser->tab_strip_model()->GetActiveWebContents();
713 EXPECT_EQ(webui_url, new_tab->GetURL());
714 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
715 new_tab->GetRenderViewHost()->GetEnabledBindings());
718 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) {
719 ui_test_utils::NavigateToURL(browser(), url1_);
720 ui_test_utils::NavigateToURL(browser(), url2_);
721 ui_test_utils::NavigateToURL(browser(), url3_);
723 GoBack(browser());
724 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
725 ASSERT_EQ(1u, active_browser_list_->size());
726 ASSERT_EQ(url2_,
727 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
728 GoForward(new_browser);
729 ASSERT_EQ(url3_,
730 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
731 GoBack(new_browser);
732 ASSERT_EQ(url2_,
733 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
735 // Test renderer-initiated back/forward as well.
736 GURL go_back_url("javascript:history.back();");
737 ui_test_utils::NavigateToURL(new_browser, go_back_url);
738 ASSERT_EQ(url1_,
739 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
742 // Tests that the SiteInstances used for entries in a restored tab's history
743 // are given appropriate max page IDs, so that going back to a restored
744 // cross-site page and then forward again works. (Bug 1204135)
745 // This test fails. See http://crbug.com/237497.
746 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
747 DISABLED_RestoresCrossSiteForwardAndBackwardNavs) {
748 ASSERT_TRUE(test_server()->Start());
750 GURL cross_site_url(test_server()->GetURL("files/title2.html"));
752 // Visit URLs on different sites.
753 ui_test_utils::NavigateToURL(browser(), url1_);
754 ui_test_utils::NavigateToURL(browser(), cross_site_url);
755 ui_test_utils::NavigateToURL(browser(), url2_);
757 GoBack(browser());
758 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
759 ASSERT_EQ(1u, active_browser_list_->size());
760 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
762 // Check that back and forward work as expected.
763 ASSERT_EQ(cross_site_url,
764 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
766 GoBack(new_browser);
767 ASSERT_EQ(url1_,
768 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
770 GoForward(new_browser);
771 ASSERT_EQ(cross_site_url,
772 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
774 // Test renderer-initiated back/forward as well.
775 GURL go_forward_url("javascript:history.forward();");
776 ui_test_utils::NavigateToURL(new_browser, go_forward_url);
777 ASSERT_EQ(url2_,
778 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
781 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) {
782 ui_test_utils::NavigateToURL(browser(), url1_);
784 ui_test_utils::NavigateToURLWithDisposition(
785 browser(), url2_, NEW_FOREGROUND_TAB,
786 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
788 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
790 ASSERT_EQ(1u, active_browser_list_->size());
791 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
792 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
793 ASSERT_EQ(url2_,
794 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
796 ASSERT_EQ(url1_,
797 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
800 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
801 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) {
802 ui_test_utils::NavigateToURL(browser(), url1_);
804 ui_test_utils::NavigateToURLWithDisposition(
805 browser(), url2_, NEW_FOREGROUND_TAB,
806 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
807 chrome::CloseTab(browser());
809 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
811 AssertOneWindowWithOneTab(new_browser);
812 ASSERT_EQ(url1_,
813 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
816 // Ensures active tab properly restored when tabs before it closed.
817 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtClose) {
818 ui_test_utils::NavigateToURL(browser(), url1_);
819 ui_test_utils::NavigateToURLWithDisposition(
820 browser(), url2_, NEW_FOREGROUND_TAB,
821 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
822 ui_test_utils::NavigateToURLWithDisposition(
823 browser(), url3_, NEW_BACKGROUND_TAB,
824 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
826 browser()->tab_strip_model()->CloseWebContentsAt(
828 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
830 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
832 ASSERT_EQ(url2_,
833 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
834 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 0);
837 // Ensures active tab properly restored when tabs are inserted before it .
838 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtInsert) {
839 ui_test_utils::NavigateToURL(browser(), url1_);
840 ui_test_utils::NavigateToURLWithDisposition(
841 browser(), url2_, NEW_BACKGROUND_TAB,
842 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
844 chrome::NavigateParams navigate_params(browser(), url3_,
845 content::PAGE_TRANSITION_TYPED);
846 navigate_params.tabstrip_index = 0;
847 navigate_params.disposition = NEW_BACKGROUND_TAB;
848 ui_test_utils::NavigateToURL(&navigate_params);
850 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
852 ASSERT_EQ(url1_,
853 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
854 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1);
857 // Creates a tabbed browser and popup and makes sure we restore both.
858 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NormalAndPopup) {
859 if (!browser_defaults::kRestorePopups)
860 return; // Test only applicable if restoring popups.
862 ui_test_utils::NavigateToURL(browser(), url1_);
864 // Make sure we have one window.
865 AssertOneWindowWithOneTab(browser());
867 // Open a popup.
868 Browser* popup = new Browser(
869 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(),
870 browser()->host_desktop_type()));
871 popup->window()->Show();
872 ASSERT_EQ(2u, active_browser_list_->size());
874 ui_test_utils::NavigateToURL(popup, url1_);
876 // Simulate an exit by shuting down the session service. If we don't do this
877 // the first window close is treated as though the user closed the window
878 // and won't be restored.
879 SessionServiceFactory::ShutdownForProfile(browser()->profile());
881 // Restart and make sure we have two windows.
882 QuitBrowserAndRestore(browser(), 1);
884 ASSERT_EQ(2u, active_browser_list_->size());
886 Browser* browser1 = active_browser_list_->get(0);
887 Browser* browser2 = active_browser_list_->get(1);
889 Browser::Type type1 = browser1->type();
890 Browser::Type type2 = browser2->type();
892 // The order of whether the normal window or popup is first depends upon
893 // activation order, which is not necessarily consistant across runs.
894 if (type1 == Browser::TYPE_TABBED) {
895 EXPECT_EQ(type2, Browser::TYPE_POPUP);
896 } else {
897 EXPECT_EQ(type1, Browser::TYPE_POPUP);
898 EXPECT_EQ(type2, Browser::TYPE_TABBED);
902 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
903 // This test doesn't apply to the Mac version; see GetCommandLineForRelaunch
904 // for details. It was disabled for a long time so might never have worked on
905 // ChromeOS.
907 // Launches an app window, closes tabbed browser, launches and makes sure
908 // we restore the tabbed browser url.
909 // If this test flakes, use http://crbug.com/29110
910 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
911 RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
912 #if defined(OS_WIN) && defined(USE_ASH)
913 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
914 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
915 return;
916 #endif
918 ui_test_utils::NavigateToURL(browser(), url1_);
920 // Launch an app.
921 CommandLine app_launch_arguments = GetCommandLineForRelaunch();
922 app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
924 ui_test_utils::BrowserAddedObserver window_observer;
926 base::LaunchProcess(app_launch_arguments, base::LaunchOptions(), NULL);
928 Browser* app_window = window_observer.WaitForSingleNewBrowser();
929 ASSERT_EQ(2u, active_browser_list_->size());
931 // Close the first window. The only window left is the App window.
932 CloseBrowserSynchronously(browser());
934 // Restore the session, which should bring back the first window with url1_.
935 Browser* new_browser = QuitBrowserAndRestore(app_window, 1);
937 AssertOneWindowWithOneTab(new_browser);
939 ASSERT_EQ(url1_,
940 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
943 #endif // !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
945 // Creates two windows, closes one, restores, make sure only one window open.
946 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) {
947 ui_test_utils::NavigateToURL(browser(), url1_);
949 // Open a second window.
950 ui_test_utils::NavigateToURLWithDisposition(
951 browser(), GURL(content::kAboutBlankURL), NEW_WINDOW,
952 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
954 ASSERT_EQ(2u, active_browser_list_->size());
956 // Close it.
957 Browser* new_window = active_browser_list_->get(1);
958 CloseBrowserSynchronously(new_window);
960 // Restart and make sure we have only one window with one tab and the url
961 // is url1_.
962 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
964 AssertOneWindowWithOneTab(new_browser);
966 ASSERT_EQ(url1_,
967 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
970 // Make sure after a restore the number of processes matches that of the number
971 // of processes running before the restore. This creates a new tab so that
972 // we should have two new tabs running. (This test will pass in both
973 // process-per-site and process-per-site-instance, because we treat the new tab
974 // as a special case in process-per-site-instance so that it only ever uses one
975 // process.)
977 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
978 // Unfortunately, the fix at http://codereview.chromium.org/6546078
979 // breaks NTP background image refreshing, so ThemeSource had to revert to
980 // replacing the existing data source.
981 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) {
982 // Create two new tabs.
983 ui_test_utils::NavigateToURLWithDisposition(
984 browser(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB,
985 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
986 ui_test_utils::NavigateToURLWithDisposition(
987 browser(), GURL(content::kAboutBlankURL), NEW_FOREGROUND_TAB,
988 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
990 int expected_process_count = RenderProcessHostCount();
992 // Restart.
993 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
995 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
997 ASSERT_EQ(expected_process_count, RenderProcessHostCount());
1000 // Test that changing the user agent override will persist it to disk.
1001 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, PersistAndRestoreUserAgentOverride) {
1002 // Create a tab with an overridden user agent.
1003 ui_test_utils::NavigateToURL(browser(), url1_);
1004 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1005 browser()->tab_strip_model()->GetWebContentsAt(0)->
1006 SetUserAgentOverride("override");
1008 // Create a tab without an overridden user agent.
1009 ui_test_utils::NavigateToURLWithDisposition(
1010 browser(), url2_, NEW_FOREGROUND_TAB,
1011 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1012 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1014 // Kill the original browser then open a new one to trigger a restore.
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(1, new_browser->tab_strip_model()->active_index());
1020 // Confirm that the user agent overrides are properly set.
1021 EXPECT_EQ("override",
1022 new_browser->tab_strip_model()->GetWebContentsAt(0)->
1023 GetUserAgentOverride());
1024 EXPECT_EQ("",
1025 new_browser->tab_strip_model()->GetWebContentsAt(1)->
1026 GetUserAgentOverride());
1029 // Regression test for crbug.com/125958. When restoring a pinned selected tab in
1030 // a setting where there are existing tabs, the selected index computation was
1031 // wrong, leading to the wrong tab getting selected, DCHECKs firing, and the
1032 // pinned tab not getting loaded.
1033 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestorePinnedSelectedTab) {
1034 // Create a pinned tab.
1035 ui_test_utils::NavigateToURL(browser(), url1_);
1036 browser()->tab_strip_model()->SetTabPinned(0, true);
1037 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1038 // Create a nonpinned tab.
1039 ui_test_utils::NavigateToURLWithDisposition(
1040 browser(), url2_, NEW_FOREGROUND_TAB,
1041 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1042 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1043 // Select the pinned tab.
1044 browser()->tab_strip_model()->ActivateTabAt(0, true);
1045 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1046 Profile* profile = browser()->profile();
1048 // This will also initiate a session restore, but we're not interested in it.
1049 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1050 ASSERT_EQ(1u, active_browser_list_->size());
1051 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1052 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1053 // Close the pinned tab.
1054 chrome::CloseTab(new_browser);
1055 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1056 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1057 // Use the existing tab to navigate away, so that we can verify it was really
1058 // clobbered.
1059 ui_test_utils::NavigateToURL(new_browser, url3_);
1061 // Restore the session again, clobbering the existing tab.
1062 SessionRestore::RestoreSession(
1063 profile, new_browser,
1064 new_browser->host_desktop_type(),
1065 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1066 std::vector<GURL>());
1068 // The pinned tab is the selected tab.
1069 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1070 EXPECT_EQ(0, new_browser->tab_strip_model()->active_index());
1071 EXPECT_EQ(url1_,
1072 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1073 EXPECT_EQ(url2_,
1074 new_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL());
1077 // Regression test for crbug.com/240156. When restoring tabs with a navigation,
1078 // the navigation should take active tab focus.
1079 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWithNavigateSelectedTab) {
1080 // Create 2 tabs.
1081 ui_test_utils::NavigateToURL(browser(), url1_);
1082 ui_test_utils::NavigateToURLWithDisposition(
1083 browser(), url2_, NEW_FOREGROUND_TAB,
1084 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1086 // Restore the session by calling chrome::Navigate().
1087 Browser* new_browser = QuitBrowserAndRestoreWithURL(browser(), 3, url3_);
1088 ASSERT_EQ(1u, active_browser_list_->size());
1089 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1090 // Navigated url should be the active tab.
1091 ASSERT_EQ(url3_,
1092 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1095 // Do a clobber restore from the new tab page. This test follows the code path
1096 // of a crash followed by the user clicking restore from the new tab page.
1097 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClobberRestoreTest) {
1098 // Create 2 tabs.
1099 ui_test_utils::NavigateToURL(browser(), url1_);
1100 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1101 ui_test_utils::NavigateToURLWithDisposition(
1102 browser(), url2_, NEW_FOREGROUND_TAB,
1103 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1104 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1105 Profile* profile = browser()->profile();
1107 // This will also initiate a session restore, but we're not interested in it.
1108 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1109 ASSERT_EQ(1u, active_browser_list_->size());
1110 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1111 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1112 // Close the first tab.
1113 chrome::CloseTab(new_browser);
1114 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1115 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1116 // Use the existing tab to navigate to the NTP.
1117 ui_test_utils::NavigateToURL(new_browser, GURL(chrome::kChromeUINewTabURL));
1119 // Restore the session again, clobbering the existing tab.
1120 SessionRestore::RestoreSession(
1121 profile, new_browser,
1122 new_browser->host_desktop_type(),
1123 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1124 std::vector<GURL>());
1126 // 2 tabs should have been restored, with the existing tab clobbered, giving
1127 // us a total of 2 tabs.
1128 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1129 EXPECT_EQ(1, new_browser->tab_strip_model()->active_index());
1130 EXPECT_EQ(url1_,
1131 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
1132 EXPECT_EQ(url2_,
1133 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1136 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) {
1137 ui_test_utils::NavigateToURL(browser(), url1_);
1138 content::NavigationController* controller =
1139 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1140 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1141 std::string session_storage_persistent_id =
1142 controller->GetDefaultSessionStorageNamespace()->persistent_id();
1143 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1144 ASSERT_EQ(1u, active_browser_list_->size());
1145 ASSERT_EQ(url1_,
1146 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1147 content::NavigationController* new_controller =
1148 &new_browser->tab_strip_model()->GetActiveWebContents()->GetController();
1149 ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace());
1150 std::string restored_session_storage_persistent_id =
1151 new_controller->GetDefaultSessionStorageNamespace()->persistent_id();
1152 EXPECT_EQ(session_storage_persistent_id,
1153 restored_session_storage_persistent_id);
1156 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) {
1157 // Simulate what prerendering does: create a new WebContents with the same
1158 // SessionStorageNamespace as an existing tab, then replace the tab with it.
1160 content::NavigationController* controller =
1161 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1162 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1164 content::SessionStorageNamespaceMap session_storage_namespace_map;
1165 session_storage_namespace_map[std::string()] =
1166 controller->GetDefaultSessionStorageNamespace();
1167 scoped_ptr<content::WebContents> web_contents(
1168 content::WebContents::CreateWithSessionStorage(
1169 content::WebContents::CreateParams(browser()->profile()),
1170 session_storage_namespace_map));
1172 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1173 scoped_ptr<content::WebContents> old_web_contents(
1174 tab_strip_model->ReplaceWebContentsAt(
1175 tab_strip_model->active_index(), web_contents.release()));
1176 // Navigate with the new tab.
1177 ui_test_utils::NavigateToURL(browser(), url2_);
1178 // old_web_contents goes out of scope.
1181 // Check that the sessionStorage data is going to be persisted.
1182 content::NavigationController* controller =
1183 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1184 EXPECT_TRUE(
1185 controller->GetDefaultSessionStorageNamespace()->should_persist());
1187 // Quit and restore. Check that no extra tabs were created.
1188 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1189 ASSERT_EQ(1u, active_browser_list_->size());
1190 EXPECT_EQ(1, new_browser->tab_strip_model()->count());