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