Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / sessions / session_restore_browsertest.cc
blob6b8b5745b8039cb2c47906d5de31b8bd17ba4a99
1 // Copyright 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/memory/memory_pressure_listener.h"
10 #include "base/process/launch.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "chrome/browser/browser_process.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_restore_test_helper.h"
20 #include "chrome/browser/sessions/session_service.h"
21 #include "chrome/browser/sessions/session_service_factory.h"
22 #include "chrome/browser/sessions/session_service_test_helper.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 "components/sessions/session_types.h"
39 #include "content/public/browser/navigation_controller.h"
40 #include "content/public/browser/navigation_entry.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/notification_types.h"
43 #include "content/public/browser/render_process_host.h"
44 #include "content/public/browser/render_view_host.h"
45 #include "content/public/browser/web_contents.h"
46 #include "content/public/common/bindings_policy.h"
47 #include "content/public/test/browser_test_utils.h"
48 #include "content/public/test/test_navigation_observer.h"
49 #include "sync/protocol/session_specifics.pb.h"
50 #include "ui/base/page_transition_types.h"
52 using sessions::SerializedNavigationEntry;
53 using sessions::SerializedNavigationEntryTestHelper;
55 #if defined(OS_MACOSX)
56 #include "base/mac/scoped_nsautorelease_pool.h"
57 #endif
59 #if defined(USE_AURA)
60 #include "ui/aura/window.h"
61 #endif
63 class SessionRestoreTest : public InProcessBrowserTest {
64 public:
65 SessionRestoreTest() : active_browser_list_(NULL) {}
67 protected:
68 #if defined(OS_CHROMEOS)
69 void SetUpCommandLine(base::CommandLine* command_line) override {
70 // TODO(nkostylev): Investigate if we can remove this switch.
71 command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests);
72 InProcessBrowserTest::SetUpCommandLine(command_line);
74 #endif
76 void SetUpOnMainThread() override {
77 active_browser_list_ = BrowserList::GetInstance(chrome::GetActiveDesktop());
79 SessionStartupPref pref(SessionStartupPref::LAST);
80 SessionStartupPref::SetStartupPref(browser()->profile(), pref);
81 #if defined(OS_CHROMEOS)
82 const testing::TestInfo* const test_info =
83 testing::UnitTest::GetInstance()->current_test_info();
84 if (strcmp(test_info->name(), "NoSessionRestoreNewWindowChromeOS") != 0) {
85 // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we
86 // can get these test to work without quitting.
87 SessionServiceTestHelper helper(
88 SessionServiceFactory::GetForProfile(browser()->profile()));
89 helper.SetForceBrowserNotAliveWithNoWindows(true);
90 helper.ReleaseService();
92 #endif
94 InProcessBrowserTest::SetUpOnMainThread();
97 bool SetUpUserDataDirectory() override {
98 url1_ = ui_test_utils::GetTestUrl(
99 base::FilePath().AppendASCII("session_history"),
100 base::FilePath().AppendASCII("bot1.html"));
101 url2_ = ui_test_utils::GetTestUrl(
102 base::FilePath().AppendASCII("session_history"),
103 base::FilePath().AppendASCII("bot2.html"));
104 url3_ = ui_test_utils::GetTestUrl(
105 base::FilePath().AppendASCII("session_history"),
106 base::FilePath().AppendASCII("bot3.html"));
108 return InProcessBrowserTest::SetUpUserDataDirectory();
111 Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) {
112 return QuitBrowserAndRestoreWithURL(
113 browser, expected_tab_count, GURL(), true);
116 Browser* QuitBrowserAndRestoreWithURL(Browser* browser,
117 int expected_tab_count,
118 const GURL& url,
119 bool no_memory_pressure) {
120 Profile* profile = browser->profile();
122 // Close the browser.
123 g_browser_process->AddRefModule();
124 CloseBrowserSynchronously(browser);
126 // Create a new window, which should trigger session restore.
127 ui_test_utils::BrowserAddedObserver window_observer;
128 SessionRestoreTestHelper restore_observer;
129 if (url.is_empty()) {
130 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
131 } else {
132 chrome::NavigateParams params(profile,
133 url,
134 ui::PAGE_TRANSITION_LINK);
135 chrome::Navigate(&params);
137 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
138 // Stop loading anything more if we are running out of space.
139 if (!no_memory_pressure) {
140 base::MemoryPressureListener::NotifyMemoryPressure(
141 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
143 restore_observer.Wait();
145 if (no_memory_pressure)
146 WaitForTabsToLoad(new_browser);
148 g_browser_process->ReleaseModule();
150 return new_browser;
153 void GoBack(Browser* browser) {
154 content::TestNavigationObserver observer(
155 browser->tab_strip_model()->GetActiveWebContents());
156 chrome::GoBack(browser, CURRENT_TAB);
157 observer.Wait();
160 void GoForward(Browser* browser) {
161 content::TestNavigationObserver observer(
162 browser->tab_strip_model()->GetActiveWebContents());
163 chrome::GoForward(browser, CURRENT_TAB);
164 observer.Wait();
167 void AssertOneWindowWithOneTab(Browser* browser) {
168 ASSERT_EQ(1u, active_browser_list_->size());
169 ASSERT_EQ(1, browser->tab_strip_model()->count());
172 int RenderProcessHostCount() {
173 content::RenderProcessHost::iterator hosts =
174 content::RenderProcessHost::AllHostsIterator();
175 int count = 0;
176 while (!hosts.IsAtEnd()) {
177 if (hosts.GetCurrentValue()->HasConnection())
178 count++;
179 hosts.Advance();
181 return count;
184 void WaitForTabsToLoad(Browser* browser) {
185 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
186 content::WebContents* contents =
187 browser->tab_strip_model()->GetWebContentsAt(i);
188 contents->GetController().LoadIfNecessary();
189 content::WaitForLoadStop(contents);
193 GURL url1_;
194 GURL url2_;
195 GURL url3_;
197 const BrowserList* active_browser_list_;
200 // Activates the smart restore behaviour in "simple" mode and tracks the loading
201 // of tabs.
202 class SmartSessionRestoreSimpleTest : public SessionRestoreTest,
203 public content::NotificationObserver {
204 public:
205 SmartSessionRestoreSimpleTest() {}
206 void StartObserving(int num_tabs) {
207 // Start by clearing everything so it can be reused in the same test.
208 web_contents_.clear();
209 registrar_.RemoveAll();
210 num_tabs_ = num_tabs;
211 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
212 content::NotificationService::AllSources());
214 void Observe(int type,
215 const content::NotificationSource& source,
216 const content::NotificationDetails& details) override {
217 switch (type) {
218 case content::NOTIFICATION_LOAD_START: {
219 content::NavigationController* controller =
220 content::Source<content::NavigationController>(source).ptr();
221 web_contents_.push_back(controller->GetWebContents());
222 if (web_contents_.size() == static_cast<size_t>(num_tabs_))
223 message_loop_runner_->Quit();
224 break;
228 const std::vector<content::WebContents*>& web_contents() const {
229 return web_contents_;
232 void WaitForAllTabsToStartLoading() {
233 message_loop_runner_ = new content::MessageLoopRunner;
234 message_loop_runner_->Run();
237 protected:
238 static const int kExpectedNumTabs;
239 static const char* const kUrls[];
240 void SetUpCommandLine(base::CommandLine* command_line) override {
241 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
242 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/");
243 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
244 switches::kForceFieldTrialParams,
245 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/simple");
248 private:
249 content::NotificationRegistrar registrar_;
250 // Ordered by load start order.
251 std::vector<content::WebContents*> web_contents_;
252 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
253 int num_tabs_;
255 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreSimpleTest);
258 class SmartSessionRestoreMRUTest : public SmartSessionRestoreSimpleTest {
259 public:
260 SmartSessionRestoreMRUTest() {}
262 protected:
263 void SetUpCommandLine(base::CommandLine* command_line) override {
264 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
265 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/");
266 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
267 switches::kForceFieldTrialParams,
268 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/mru");
271 private:
272 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreMRUTest);
275 // static
276 const int SmartSessionRestoreSimpleTest::kExpectedNumTabs = 6;
277 // static
278 const char* const SmartSessionRestoreSimpleTest::kUrls[] = {
279 "http://google.com/1",
280 "http://google.com/2",
281 "http://google.com/3",
282 "http://google.com/4",
283 "http://google.com/5",
284 "http://google.com/6"};
286 // Verifies that restored tabs have a root window. This is important
287 // otherwise the wrong information is communicated to the renderer.
288 // (http://crbug.com/342672).
289 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveWindow) {
290 // Create tabs.
291 ui_test_utils::NavigateToURLWithDisposition(
292 browser(),
293 GURL(url::kAboutBlankURL),
294 NEW_FOREGROUND_TAB,
295 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
296 ui_test_utils::NavigateToURLWithDisposition(
297 browser(),
298 GURL(url::kAboutBlankURL),
299 NEW_BACKGROUND_TAB,
300 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
302 // Restart and session restore the tabs.
303 Browser* restored = QuitBrowserAndRestore(browser(), 3);
304 TabStripModel* tab_strip_model = restored->tab_strip_model();
305 const int tabs = tab_strip_model->count();
306 ASSERT_EQ(3, tabs);
308 // Check the restored tabs have a window to get screen info from.
309 // On Aura it should also have a root window.
310 for (int i = 0; i < tabs; ++i) {
311 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
312 EXPECT_TRUE(contents->GetTopLevelNativeWindow());
313 #if defined(USE_AURA)
314 EXPECT_TRUE(contents->GetNativeView()->GetRootWindow());
315 #endif
319 // Verify that restored tabs have correct disposition. Only one tab should
320 // have "visible" visibility state, the rest should not.
321 // (http://crbug.com/155365 http://crbug.com/118269)
322 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
323 RestoredTabsHaveCorrectVisibilityState) {
324 // Create tabs.
325 GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(),
326 base::FilePath(FILE_PATH_LITERAL("tab-restore-visibilty.html"))));
327 ui_test_utils::NavigateToURLWithDisposition(
328 browser(), test_page, NEW_FOREGROUND_TAB,
329 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
330 ui_test_utils::NavigateToURLWithDisposition(
331 browser(), test_page, NEW_BACKGROUND_TAB,
332 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
334 // Restart and session restore the tabs.
335 content::DOMMessageQueue message_queue;
336 Browser* restored = QuitBrowserAndRestore(browser(), 3);
337 for (int i = 0; i < 2; ++i) {
338 std::string message;
339 EXPECT_TRUE(message_queue.WaitForMessage(&message));
340 EXPECT_EQ("\"READY\"", message);
343 // There should be 3 restored tabs in the new browser.
344 TabStripModel* tab_strip_model = restored->tab_strip_model();
345 const int tabs = tab_strip_model->count();
346 ASSERT_EQ(3, tabs);
348 // The middle tab only should have visible disposition.
349 for (int i = 0; i < tabs; ++i) {
350 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
351 std::string document_visibility_state;
352 const char kGetStateJS[] = "window.domAutomationController.send("
353 "window.document.visibilityState);";
354 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
355 contents, kGetStateJS, &document_visibility_state));
356 if (i == 1) {
357 EXPECT_EQ("visible", document_visibility_state);
358 } else {
359 EXPECT_EQ("hidden", document_visibility_state);
364 #if defined(OS_CHROMEOS)
365 // Verify that session restore does not occur when a user opens a browser window
366 // when no other browser windows are open on ChromeOS.
367 // TODO(pkotwicz): Add test which doesn't open incognito browser once
368 // disable-zero-browsers-open-for-tests is removed.
369 // (http://crbug.com/119175)
370 // TODO(pkotwicz): Mac should have the behavior outlined by this test. It should
371 // not do session restore if an incognito window is already open.
372 // (http://crbug.com/120927)
373 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) {
374 GURL url(ui_test_utils::GetTestUrl(
375 base::FilePath(base::FilePath::kCurrentDirectory),
376 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
378 // Add a single tab.
379 ui_test_utils::NavigateToURL(browser(), url);
381 Browser* incognito_browser = CreateIncognitoBrowser();
382 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
383 incognito_browser->window()->Show();
385 // Close the normal browser. After this we only have the incognito window
386 // open.
387 CloseBrowserSynchronously(browser());
389 // Create a new window, which should open NTP.
390 ui_test_utils::BrowserAddedObserver browser_added_observer;
391 chrome::NewWindow(incognito_browser);
392 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
394 ASSERT_TRUE(new_browser);
395 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
396 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
397 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
400 // Test that maximized applications get restored maximized.
401 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MaximizedApps) {
402 const char* app_name = "TestApp";
403 Browser* app_browser = CreateBrowserForApp(app_name, browser()->profile());
404 app_browser->window()->Maximize();
405 app_browser->window()->Show();
406 EXPECT_TRUE(app_browser->window()->IsMaximized());
407 EXPECT_TRUE(app_browser->is_app());
408 EXPECT_TRUE(app_browser->is_type_popup());
410 // Close the normal browser. After this we only have the app_browser window.
411 CloseBrowserSynchronously(browser());
413 // Create a new window, which should open NTP.
414 ui_test_utils::BrowserAddedObserver browser_added_observer;
415 chrome::NewWindow(app_browser);
416 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
418 ASSERT_TRUE(new_browser);
419 EXPECT_TRUE(app_browser->window()->IsMaximized());
420 EXPECT_TRUE(app_browser->is_app());
421 EXPECT_TRUE(app_browser->is_type_popup());
423 #endif // OS_CHROMEOS
425 #if !defined(OS_CHROMEOS)
426 // This test does not apply to ChromeOS as it does not do session restore when
427 // a new window is opened.
429 #if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
430 // Crashes on Linux Views: http://crbug.com/39476
431 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
432 DISABLED_RestoreOnNewWindowWithNoTabbedBrowsers
433 #else
434 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
435 RestoreOnNewWindowWithNoTabbedBrowsers
436 #endif
438 // Makes sure when session restore is triggered in the same process we don't end
439 // up with an extra tab.
440 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
441 MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers) {
442 const base::FilePath::CharType* kTitle1File =
443 FILE_PATH_LITERAL("title1.html");
444 GURL url(ui_test_utils::GetTestUrl(base::FilePath(
445 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
446 ui_test_utils::NavigateToURL(browser(), url);
448 // Turn on session restore.
449 SessionStartupPref::SetStartupPref(
450 browser()->profile(),
451 SessionStartupPref(SessionStartupPref::LAST));
453 // Create a new popup.
454 Profile* profile = browser()->profile();
455 Browser* popup =
456 new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile,
457 browser()->host_desktop_type()));
458 popup->window()->Show();
460 // Close the browser.
461 CloseBrowserSynchronously(browser());
463 // Create a new window, which should trigger session restore.
464 ui_test_utils::BrowserAddedObserver observer;
465 chrome::NewWindow(popup);
466 Browser* new_browser = observer.WaitForSingleNewBrowser();
468 ASSERT_TRUE(new_browser != NULL);
470 // The browser should only have one tab.
471 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
473 // And the first url should be url.
474 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
476 #endif // !OS_CHROMEOS
478 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreIndividualTabFromWindow) {
479 GURL url1(ui_test_utils::GetTestUrl(
480 base::FilePath(base::FilePath::kCurrentDirectory),
481 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
482 // Any page that will yield a 200 status code will work here.
483 GURL url2("chrome://version");
484 GURL url3(ui_test_utils::GetTestUrl(
485 base::FilePath(base::FilePath::kCurrentDirectory),
486 base::FilePath(FILE_PATH_LITERAL("title3.html"))));
488 // Add and navigate three tabs.
489 ui_test_utils::NavigateToURL(browser(), url1);
491 content::WindowedNotificationObserver observer(
492 content::NOTIFICATION_LOAD_STOP,
493 content::NotificationService::AllSources());
494 chrome::AddSelectedTabWithURL(browser(), url2,
495 ui::PAGE_TRANSITION_LINK);
496 observer.Wait();
499 content::WindowedNotificationObserver observer(
500 content::NOTIFICATION_LOAD_STOP,
501 content::NotificationService::AllSources());
502 chrome::AddSelectedTabWithURL(browser(), url3,
503 ui::PAGE_TRANSITION_LINK);
504 observer.Wait();
507 TabRestoreService* service =
508 TabRestoreServiceFactory::GetForProfile(browser()->profile());
509 service->ClearEntries();
511 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
513 browser()->window()->Close();
515 // Expect a window with three tabs.
516 ASSERT_EQ(1U, service->entries().size());
517 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
518 const TabRestoreService::Window* window =
519 static_cast<TabRestoreService::Window*>(service->entries().front());
520 EXPECT_EQ(3U, window->tabs.size());
522 // Find the SessionID for entry2. Since the session service was destroyed,
523 // there is no guarantee that the SessionID for the tab has remained the same.
524 base::Time timestamp;
525 int http_status_code = 0;
526 for (std::vector<TabRestoreService::Tab>::const_iterator it =
527 window->tabs.begin(); it != window->tabs.end(); ++it) {
528 const TabRestoreService::Tab& tab = *it;
529 // If this tab held url2, then restore this single tab.
530 if (tab.navigations[0].virtual_url() == url2) {
531 timestamp = tab.navigations[0].timestamp();
532 http_status_code = tab.navigations[0].http_status_code();
533 std::vector<content::WebContents*> content =
534 service->RestoreEntryById(NULL, tab.id, host_desktop_type, UNKNOWN);
535 ASSERT_EQ(1U, content.size());
536 ASSERT_TRUE(content[0]);
537 EXPECT_EQ(url2, content[0]->GetURL());
538 break;
541 EXPECT_FALSE(timestamp.is_null());
542 EXPECT_EQ(200, http_status_code);
544 // Make sure that the restored tab is removed from the service.
545 ASSERT_EQ(1U, service->entries().size());
546 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
547 window = static_cast<TabRestoreService::Window*>(service->entries().front());
548 EXPECT_EQ(2U, window->tabs.size());
550 // Make sure that the restored tab was restored with the correct
551 // timestamp and status code.
552 const content::WebContents* contents =
553 browser()->tab_strip_model()->GetActiveWebContents();
554 ASSERT_TRUE(contents);
555 const content::NavigationEntry* entry =
556 contents->GetController().GetActiveEntry();
557 ASSERT_TRUE(entry);
558 EXPECT_EQ(timestamp, entry->GetTimestamp());
559 EXPECT_EQ(http_status_code, entry->GetHttpStatusCode());
562 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) {
563 GURL url(ui_test_utils::GetTestUrl(
564 base::FilePath(base::FilePath::kCurrentDirectory),
565 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
567 // Add a single tab.
568 ui_test_utils::NavigateToURL(browser(), url);
570 TabRestoreService* service =
571 TabRestoreServiceFactory::GetForProfile(browser()->profile());
572 service->ClearEntries();
573 EXPECT_EQ(0U, service->entries().size());
575 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
577 // Close the window.
578 browser()->window()->Close();
580 // Expect the window to be converted to a tab by the TRS.
581 EXPECT_EQ(1U, service->entries().size());
582 ASSERT_EQ(TabRestoreService::TAB, service->entries().front()->type);
583 const TabRestoreService::Tab* tab =
584 static_cast<TabRestoreService::Tab*>(service->entries().front());
586 // Restore the tab.
587 std::vector<content::WebContents*> content =
588 service->RestoreEntryById(NULL, tab->id, host_desktop_type, UNKNOWN);
589 ASSERT_EQ(1U, content.size());
590 ASSERT_TRUE(content[0]);
591 EXPECT_EQ(url, content[0]->GetURL());
593 // Make sure the restore was successful.
594 EXPECT_EQ(0U, service->entries().size());
597 #if !defined(OS_CHROMEOS)
598 // This test does not apply to ChromeOS as ChromeOS does not do session
599 // restore when a new window is open.
601 // Verifies we remember the last browser window when closing the last
602 // non-incognito window while an incognito window is open.
603 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) {
604 GURL url(ui_test_utils::GetTestUrl(
605 base::FilePath(base::FilePath::kCurrentDirectory),
606 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
608 // Add a single tab.
609 ui_test_utils::NavigateToURL(browser(), url);
611 // Create a new incognito window.
612 Browser* incognito_browser = CreateIncognitoBrowser();
613 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
614 incognito_browser->window()->Show();
616 // Close the normal browser. After this we only have the incognito window
617 // open.
618 CloseBrowserSynchronously(browser());
620 // Create a new window, which should trigger session restore.
621 ui_test_utils::BrowserAddedObserver browser_added_observer;
622 chrome::NewWindow(incognito_browser);
623 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
625 // The first tab should have 'url' as its url.
626 ASSERT_TRUE(new_browser);
627 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
629 #endif // !OS_CHROMEOS
631 namespace {
633 // Verifies that the given NavigationController has exactly two
634 // entries that correspond to the given URLs and that all but the last
635 // entry have null timestamps.
636 void VerifyNavigationEntries(
637 const content::NavigationController& controller,
638 GURL url1, GURL url2) {
639 ASSERT_EQ(2, controller.GetEntryCount());
640 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
641 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
642 EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL());
643 EXPECT_TRUE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
644 EXPECT_FALSE(controller.GetEntryAtIndex(1)->GetTimestamp().is_null());
647 } // namespace
649 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) {
650 GURL url1("http://google.com");
651 GURL url2("http://google2.com");
652 SerializedNavigationEntry nav1 =
653 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
654 SerializedNavigationEntry nav2 =
655 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
657 // Set up the restore data.
658 sync_pb::SessionTab sync_data;
659 sync_data.set_tab_visual_index(0);
660 sync_data.set_current_navigation_index(1);
661 sync_data.set_pinned(false);
662 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
663 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
665 sessions::SessionTab tab;
666 tab.SetFromSyncData(sync_data, base::Time::Now());
667 EXPECT_EQ(2U, tab.navigations.size());
668 for (size_t i = 0; i < tab.navigations.size(); ++i)
669 EXPECT_TRUE(tab.navigations[i].timestamp().is_null());
671 ASSERT_EQ(1, browser()->tab_strip_model()->count());
673 // Restore in the current tab.
674 content::WebContents* tab_content = NULL;
676 content::WindowedNotificationObserver observer(
677 content::NOTIFICATION_LOAD_STOP,
678 content::NotificationService::AllSources());
679 tab_content = SessionRestore::RestoreForeignSessionTab(
680 browser()->tab_strip_model()->GetActiveWebContents(), tab, CURRENT_TAB);
681 observer.Wait();
683 ASSERT_EQ(1, browser()->tab_strip_model()->count());
684 content::WebContents* web_contents =
685 browser()->tab_strip_model()->GetWebContentsAt(0);
686 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
687 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
688 ASSERT_TRUE(tab_content);
689 ASSERT_EQ(url2, tab_content->GetURL());
691 // Restore in a new tab.
692 tab_content = NULL;
694 content::WindowedNotificationObserver observer(
695 content::NOTIFICATION_LOAD_STOP,
696 content::NotificationService::AllSources());
697 tab_content = SessionRestore::RestoreForeignSessionTab(
698 browser()->tab_strip_model()->GetActiveWebContents(),
699 tab, NEW_BACKGROUND_TAB);
700 observer.Wait();
702 ASSERT_EQ(2, browser()->tab_strip_model()->count());
703 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
704 web_contents = browser()->tab_strip_model()->GetWebContentsAt(1);
705 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
706 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
707 ASSERT_TRUE(tab_content);
708 ASSERT_EQ(url2, tab_content->GetURL());
710 // Restore in a new window.
711 Browser* new_browser = NULL;
712 tab_content = NULL;
714 ui_test_utils::BrowserAddedObserver browser_observer;
715 content::WindowedNotificationObserver observer(
716 content::NOTIFICATION_LOAD_STOP,
717 content::NotificationService::AllSources());
718 tab_content = SessionRestore::RestoreForeignSessionTab(
719 browser()->tab_strip_model()->GetActiveWebContents(), tab, NEW_WINDOW);
720 new_browser = browser_observer.WaitForSingleNewBrowser();
721 observer.Wait();
724 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
725 web_contents = new_browser->tab_strip_model()->GetWebContentsAt(0);
726 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
727 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
728 ASSERT_TRUE(tab_content);
729 ASSERT_EQ(url2, tab_content->GetURL());
732 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) {
733 Profile* profile = browser()->profile();
735 GURL url1("http://google.com");
736 GURL url2("http://google2.com");
737 SerializedNavigationEntry nav1 =
738 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
739 SerializedNavigationEntry nav2 =
740 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
741 SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav2);
743 // Set up the restore data -- one window with two tabs.
744 std::vector<const sessions::SessionWindow*> session;
745 sessions::SessionWindow window;
746 sessions::SessionTab tab1;
748 sync_pb::SessionTab sync_data;
749 sync_data.set_tab_visual_index(0);
750 sync_data.set_current_navigation_index(0);
751 sync_data.set_pinned(true);
752 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
753 tab1.SetFromSyncData(sync_data, base::Time::Now());
755 window.tabs.push_back(&tab1);
757 sessions::SessionTab tab2;
759 sync_pb::SessionTab sync_data;
760 sync_data.set_tab_visual_index(1);
761 sync_data.set_current_navigation_index(0);
762 sync_data.set_pinned(false);
763 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
764 tab2.SetFromSyncData(sync_data, base::Time::Now());
766 window.tabs.push_back(&tab2);
768 // Leave tab3 empty. Should have no effect on restored session, but simulates
769 // partially complete foreign session data.
770 sessions::SessionTab tab3;
771 window.tabs.push_back(&tab3);
773 session.push_back(static_cast<const sessions::SessionWindow*>(&window));
774 ui_test_utils::BrowserAddedObserver window_observer;
775 std::vector<Browser*> browsers =
776 SessionRestore::RestoreForeignSessionWindows(
777 profile, browser()->host_desktop_type(), session.begin(),
778 session.end());
779 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
780 ASSERT_TRUE(new_browser);
781 ASSERT_EQ(2u, active_browser_list_->size());
782 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
784 ASSERT_EQ(1u, browsers.size());
785 ASSERT_TRUE(browsers[0]);
786 ASSERT_EQ(2, browsers[0]->tab_strip_model()->count());
788 content::WebContents* web_contents_1 =
789 new_browser->tab_strip_model()->GetWebContentsAt(0);
790 content::WebContents* web_contents_2 =
791 new_browser->tab_strip_model()->GetWebContentsAt(1);
792 ASSERT_EQ(url1, web_contents_1->GetURL());
793 ASSERT_EQ(url2, web_contents_2->GetURL());
795 // Check user agent override state.
796 ASSERT_TRUE(web_contents_1->GetUserAgentOverride().empty());
797 ASSERT_TRUE(web_contents_2->GetUserAgentOverride().empty());
799 content::NavigationEntry* entry =
800 web_contents_1->GetController().GetActiveEntry();
801 ASSERT_TRUE(entry);
802 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
804 entry = web_contents_2->GetController().GetActiveEntry();
805 ASSERT_TRUE(entry);
806 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
808 // The SessionWindow destructor deletes the tabs, so we have to clear them
809 // here to avoid a crash.
810 window.tabs.clear();
813 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) {
814 ui_test_utils::NavigateToURL(browser(), url1_);
815 ui_test_utils::NavigateToURL(browser(), url2_);
817 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
818 ASSERT_EQ(1u, active_browser_list_->size());
819 ASSERT_EQ(url2_,
820 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
821 GoBack(new_browser);
822 ASSERT_EQ(url1_,
823 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
826 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoMemoryPressureLoadsAllTabs) {
827 // Add several tabs to the browser. Restart the browser and check that all
828 // tabs got loaded properly.
829 ui_test_utils::NavigateToURLWithDisposition(
830 browser(),
831 GURL(url::kAboutBlankURL),
832 NEW_FOREGROUND_TAB,
833 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
834 ui_test_utils::NavigateToURLWithDisposition(
835 browser(),
836 GURL(url::kAboutBlankURL),
837 NEW_FOREGROUND_TAB,
838 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
839 Browser* restored =
840 QuitBrowserAndRestoreWithURL(browser(), 1, GURL(), true);
841 TabStripModel* tab_strip_model = restored->tab_strip_model();
843 ASSERT_EQ(1u, active_browser_list_->size());
845 ASSERT_EQ(3, tab_strip_model->count());
846 // All render widgets should be initialized by now.
847 ASSERT_TRUE(
848 tab_strip_model->GetWebContentsAt(0)->GetRenderWidgetHostView() &&
849 tab_strip_model->GetWebContentsAt(1)->GetRenderWidgetHostView() &&
850 tab_strip_model->GetWebContentsAt(2)->GetRenderWidgetHostView());
853 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MemoryPressureLoadsNotAllTabs) {
854 // Add several tabs to the browser. Restart the browser and check that all
855 // tabs got loaded properly.
856 ui_test_utils::NavigateToURLWithDisposition(
857 browser(),
858 GURL(url::kAboutBlankURL),
859 NEW_FOREGROUND_TAB,
860 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
861 ui_test_utils::NavigateToURLWithDisposition(
862 browser(),
863 GURL(url::kAboutBlankURL),
864 NEW_FOREGROUND_TAB,
865 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
866 // Restore the brwoser, but instead of directly waiting, we issue a critical
867 // memory pressure event and finish then the loading.
868 Browser* restored =
869 QuitBrowserAndRestoreWithURL(browser(), 1, GURL(), false);
871 TabStripModel* tab_strip_model = restored->tab_strip_model();
873 ASSERT_EQ(1u, active_browser_list_->size());
875 ASSERT_EQ(3, tab_strip_model->count());
876 // At least one of the render widgets should not be initialized yet.
877 ASSERT_FALSE(
878 tab_strip_model->GetWebContentsAt(0)->GetRenderWidgetHostView() &&
879 tab_strip_model->GetWebContentsAt(1)->GetRenderWidgetHostView() &&
880 tab_strip_model->GetWebContentsAt(2)->GetRenderWidgetHostView());
883 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) {
884 const GURL webui_url("chrome://omnibox");
885 ui_test_utils::NavigateToURL(browser(), webui_url);
886 const content::WebContents* old_tab =
887 browser()->tab_strip_model()->GetActiveWebContents();
888 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
889 old_tab->GetRenderViewHost()->GetEnabledBindings());
891 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
892 ASSERT_EQ(1u, active_browser_list_->size());
893 const content::WebContents* new_tab =
894 new_browser->tab_strip_model()->GetActiveWebContents();
895 EXPECT_EQ(webui_url, new_tab->GetURL());
896 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
897 new_tab->GetRenderViewHost()->GetEnabledBindings());
900 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUISettings) {
901 const GURL webui_url("chrome://settings");
902 ui_test_utils::NavigateToURL(browser(), webui_url);
903 const content::WebContents* old_tab =
904 browser()->tab_strip_model()->GetActiveWebContents();
905 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
906 old_tab->GetRenderViewHost()->GetEnabledBindings());
908 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
909 ASSERT_EQ(1u, active_browser_list_->size());
910 const content::WebContents* new_tab =
911 new_browser->tab_strip_model()->GetActiveWebContents();
912 EXPECT_EQ(webui_url, new_tab->GetURL());
913 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
914 new_tab->GetRenderViewHost()->GetEnabledBindings());
917 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) {
918 ui_test_utils::NavigateToURL(browser(), url1_);
919 ui_test_utils::NavigateToURL(browser(), url2_);
920 ui_test_utils::NavigateToURL(browser(), url3_);
922 GoBack(browser());
923 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
924 ASSERT_EQ(1u, active_browser_list_->size());
925 ASSERT_EQ(url2_,
926 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
927 GoForward(new_browser);
928 ASSERT_EQ(url3_,
929 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
930 GoBack(new_browser);
931 ASSERT_EQ(url2_,
932 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
934 // Test renderer-initiated back/forward as well.
935 GURL go_back_url("javascript:history.back();");
936 ui_test_utils::NavigateToURL(new_browser, go_back_url);
937 ASSERT_EQ(url1_,
938 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
941 // Tests that the SiteInstances used for entries in a restored tab's history
942 // are given appropriate max page IDs, so that going back to a restored
943 // cross-site page and then forward again works. (Bug 1204135)
944 // This test fails. See http://crbug.com/237497.
945 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
946 DISABLED_RestoresCrossSiteForwardAndBackwardNavs) {
947 ASSERT_TRUE(test_server()->Start());
949 GURL cross_site_url(test_server()->GetURL("files/title2.html"));
951 // Visit URLs on different sites.
952 ui_test_utils::NavigateToURL(browser(), url1_);
953 ui_test_utils::NavigateToURL(browser(), cross_site_url);
954 ui_test_utils::NavigateToURL(browser(), url2_);
956 GoBack(browser());
957 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
958 ASSERT_EQ(1u, active_browser_list_->size());
959 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
961 // Check that back and forward work as expected.
962 ASSERT_EQ(cross_site_url,
963 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
965 GoBack(new_browser);
966 ASSERT_EQ(url1_,
967 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
969 GoForward(new_browser);
970 ASSERT_EQ(cross_site_url,
971 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
973 // Test renderer-initiated back/forward as well.
974 GURL go_forward_url("javascript:history.forward();");
975 ui_test_utils::NavigateToURL(new_browser, go_forward_url);
976 ASSERT_EQ(url2_,
977 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
980 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) {
981 ui_test_utils::NavigateToURL(browser(), url1_);
983 ui_test_utils::NavigateToURLWithDisposition(
984 browser(), url2_, NEW_FOREGROUND_TAB,
985 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
987 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
989 ASSERT_EQ(1u, active_browser_list_->size());
990 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
991 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
992 ASSERT_EQ(url2_,
993 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
995 ASSERT_EQ(url1_,
996 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
999 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
1000 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) {
1001 ui_test_utils::NavigateToURL(browser(), url1_);
1003 ui_test_utils::NavigateToURLWithDisposition(
1004 browser(), url2_, NEW_FOREGROUND_TAB,
1005 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1006 chrome::CloseTab(browser());
1008 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1010 AssertOneWindowWithOneTab(new_browser);
1011 ASSERT_EQ(url1_,
1012 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1015 // Ensures active tab properly restored when tabs before it closed.
1016 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtClose) {
1017 ui_test_utils::NavigateToURL(browser(), url1_);
1018 ui_test_utils::NavigateToURLWithDisposition(
1019 browser(), url2_, NEW_FOREGROUND_TAB,
1020 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1021 ui_test_utils::NavigateToURLWithDisposition(
1022 browser(), url3_, NEW_BACKGROUND_TAB,
1023 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1025 browser()->tab_strip_model()->CloseWebContentsAt(
1027 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
1029 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
1031 ASSERT_EQ(url2_,
1032 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1033 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 0);
1036 // Ensures active tab properly restored when tabs are inserted before it .
1037 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtInsert) {
1038 ui_test_utils::NavigateToURL(browser(), url1_);
1039 ui_test_utils::NavigateToURLWithDisposition(
1040 browser(), url2_, NEW_BACKGROUND_TAB,
1041 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1043 chrome::NavigateParams navigate_params(browser(), url3_,
1044 ui::PAGE_TRANSITION_TYPED);
1045 navigate_params.tabstrip_index = 0;
1046 navigate_params.disposition = NEW_BACKGROUND_TAB;
1047 ui_test_utils::NavigateToURL(&navigate_params);
1049 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
1051 ASSERT_EQ(url1_,
1052 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1053 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1);
1056 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
1057 // This test doesn't apply to the Mac version; see GetCommandLineForRelaunch
1058 // for details. It was disabled for a long time so might never have worked on
1059 // ChromeOS.
1061 // Launches an app window, closes tabbed browser, launches and makes sure
1062 // we restore the tabbed browser url.
1063 // If this test flakes, use http://crbug.com/29110
1064 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
1065 RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
1066 #if defined(OS_WIN) && defined(USE_ASH)
1067 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1068 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1069 switches::kAshBrowserTests))
1070 return;
1071 #endif
1073 ui_test_utils::NavigateToURL(browser(), url1_);
1075 // Launch an app.
1076 base::CommandLine app_launch_arguments = GetCommandLineForRelaunch();
1077 app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
1079 ui_test_utils::BrowserAddedObserver window_observer;
1081 base::LaunchProcess(app_launch_arguments, base::LaunchOptionsForTest());
1083 Browser* app_window = window_observer.WaitForSingleNewBrowser();
1084 ASSERT_EQ(2u, active_browser_list_->size());
1086 // Close the first window. The only window left is the App window.
1087 CloseBrowserSynchronously(browser());
1089 // Restore the session, which should bring back the first window with url1_.
1090 Browser* new_browser = QuitBrowserAndRestore(app_window, 1);
1092 AssertOneWindowWithOneTab(new_browser);
1094 ASSERT_EQ(url1_,
1095 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1098 #endif // !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
1100 // Creates two windows, closes one, restores, make sure only one window open.
1101 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) {
1102 ui_test_utils::NavigateToURL(browser(), url1_);
1104 // Open a second window.
1105 ui_test_utils::NavigateToURLWithDisposition(
1106 browser(),
1107 GURL(url::kAboutBlankURL),
1108 NEW_WINDOW,
1109 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
1111 ASSERT_EQ(2u, active_browser_list_->size());
1113 // Close it.
1114 Browser* new_window = active_browser_list_->get(1);
1115 CloseBrowserSynchronously(new_window);
1117 // Restart and make sure we have only one window with one tab and the url
1118 // is url1_.
1119 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1121 AssertOneWindowWithOneTab(new_browser);
1123 ASSERT_EQ(url1_,
1124 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1127 // Make sure after a restore the number of processes matches that of the number
1128 // of processes running before the restore. This creates a new tab so that
1129 // we should have two new tabs running. (This test will pass in both
1130 // process-per-site and process-per-site-instance, because we treat the new tab
1131 // as a special case in process-per-site-instance so that it only ever uses one
1132 // process.)
1134 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
1135 // Unfortunately, the fix at http://codereview.chromium.org/6546078
1136 // breaks NTP background image refreshing, so ThemeSource had to revert to
1137 // replacing the existing data source.
1138 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) {
1139 // Create two new tabs.
1140 ui_test_utils::NavigateToURLWithDisposition(
1141 browser(),
1142 GURL(url::kAboutBlankURL),
1143 NEW_FOREGROUND_TAB,
1144 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1145 ui_test_utils::NavigateToURLWithDisposition(
1146 browser(),
1147 GURL(url::kAboutBlankURL),
1148 NEW_FOREGROUND_TAB,
1149 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1151 int expected_process_count = RenderProcessHostCount();
1153 // Restart.
1154 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
1156 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1158 ASSERT_EQ(expected_process_count, RenderProcessHostCount());
1161 // Test that changing the user agent override will persist it to disk.
1162 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, PersistAndRestoreUserAgentOverride) {
1163 // Create a tab with an overridden user agent.
1164 ui_test_utils::NavigateToURL(browser(), url1_);
1165 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1166 browser()->tab_strip_model()->GetWebContentsAt(0)->
1167 SetUserAgentOverride("override");
1169 // Create a tab without an overridden user agent.
1170 ui_test_utils::NavigateToURLWithDisposition(
1171 browser(), url2_, NEW_FOREGROUND_TAB,
1172 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1173 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1175 // Kill the original browser then open a new one to trigger a restore.
1176 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1177 ASSERT_EQ(1u, active_browser_list_->size());
1178 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1179 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1181 // Confirm that the user agent overrides are properly set.
1182 EXPECT_EQ("override",
1183 new_browser->tab_strip_model()->GetWebContentsAt(0)->
1184 GetUserAgentOverride());
1185 EXPECT_EQ("",
1186 new_browser->tab_strip_model()->GetWebContentsAt(1)->
1187 GetUserAgentOverride());
1190 // Regression test for crbug.com/125958. When restoring a pinned selected tab in
1191 // a setting where there are existing tabs, the selected index computation was
1192 // wrong, leading to the wrong tab getting selected, DCHECKs firing, and the
1193 // pinned tab not getting loaded.
1194 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestorePinnedSelectedTab) {
1195 // Create a pinned tab.
1196 ui_test_utils::NavigateToURL(browser(), url1_);
1197 browser()->tab_strip_model()->SetTabPinned(0, true);
1198 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1199 // Create a nonpinned tab.
1200 ui_test_utils::NavigateToURLWithDisposition(
1201 browser(), url2_, NEW_FOREGROUND_TAB,
1202 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1203 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1204 // Select the pinned tab.
1205 browser()->tab_strip_model()->ActivateTabAt(0, true);
1206 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1207 Profile* profile = browser()->profile();
1209 // This will also initiate a session restore, but we're not interested in it.
1210 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1211 ASSERT_EQ(1u, active_browser_list_->size());
1212 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1213 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1214 // Close the pinned tab.
1215 chrome::CloseTab(new_browser);
1216 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1217 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1218 // Use the existing tab to navigate away, so that we can verify it was really
1219 // clobbered.
1220 ui_test_utils::NavigateToURL(new_browser, url3_);
1222 // Restore the session again, clobbering the existing tab.
1223 SessionRestore::RestoreSession(
1224 profile, new_browser,
1225 new_browser->host_desktop_type(),
1226 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1227 std::vector<GURL>());
1229 // The pinned tab is the selected tab.
1230 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1231 EXPECT_EQ(0, new_browser->tab_strip_model()->active_index());
1232 EXPECT_EQ(url1_,
1233 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1234 EXPECT_EQ(url2_,
1235 new_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL());
1238 // Regression test for crbug.com/240156. When restoring tabs with a navigation,
1239 // the navigation should take active tab focus.
1240 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWithNavigateSelectedTab) {
1241 // Create 2 tabs.
1242 ui_test_utils::NavigateToURL(browser(), url1_);
1243 ui_test_utils::NavigateToURLWithDisposition(
1244 browser(), url2_, NEW_FOREGROUND_TAB,
1245 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1247 // Restore the session by calling chrome::Navigate().
1248 Browser* new_browser =
1249 QuitBrowserAndRestoreWithURL(browser(), 3, url3_, true);
1250 ASSERT_EQ(1u, active_browser_list_->size());
1251 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1252 // Navigated url should be the active tab.
1253 ASSERT_EQ(url3_,
1254 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1257 // Do a clobber restore from the new tab page. This test follows the code path
1258 // of a crash followed by the user clicking restore from the new tab page.
1259 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClobberRestoreTest) {
1260 // Create 2 tabs.
1261 ui_test_utils::NavigateToURL(browser(), url1_);
1262 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1263 ui_test_utils::NavigateToURLWithDisposition(
1264 browser(), url2_, NEW_FOREGROUND_TAB,
1265 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1266 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1267 Profile* profile = browser()->profile();
1269 // This will also initiate a session restore, but we're not interested in it.
1270 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1271 ASSERT_EQ(1u, active_browser_list_->size());
1272 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1273 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1274 // Close the first tab.
1275 chrome::CloseTab(new_browser);
1276 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1277 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1278 // Use the existing tab to navigate to the NTP.
1279 ui_test_utils::NavigateToURL(new_browser, GURL(chrome::kChromeUINewTabURL));
1281 // Restore the session again, clobbering the existing tab.
1282 SessionRestore::RestoreSession(
1283 profile, new_browser,
1284 new_browser->host_desktop_type(),
1285 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1286 std::vector<GURL>());
1288 // 2 tabs should have been restored, with the existing tab clobbered, giving
1289 // us a total of 2 tabs.
1290 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1291 EXPECT_EQ(1, new_browser->tab_strip_model()->active_index());
1292 EXPECT_EQ(url1_,
1293 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
1294 EXPECT_EQ(url2_,
1295 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1298 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) {
1299 ui_test_utils::NavigateToURL(browser(), url1_);
1300 content::NavigationController* controller =
1301 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1302 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1303 std::string session_storage_persistent_id =
1304 controller->GetDefaultSessionStorageNamespace()->persistent_id();
1305 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1306 ASSERT_EQ(1u, active_browser_list_->size());
1307 ASSERT_EQ(url1_,
1308 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1309 content::NavigationController* new_controller =
1310 &new_browser->tab_strip_model()->GetActiveWebContents()->GetController();
1311 ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace());
1312 std::string restored_session_storage_persistent_id =
1313 new_controller->GetDefaultSessionStorageNamespace()->persistent_id();
1314 EXPECT_EQ(session_storage_persistent_id,
1315 restored_session_storage_persistent_id);
1318 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) {
1319 // Simulate what prerendering does: create a new WebContents with the same
1320 // SessionStorageNamespace as an existing tab, then replace the tab with it.
1322 content::NavigationController* controller =
1323 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1324 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1326 content::SessionStorageNamespaceMap session_storage_namespace_map;
1327 session_storage_namespace_map[std::string()] =
1328 controller->GetDefaultSessionStorageNamespace();
1329 scoped_ptr<content::WebContents> web_contents(
1330 content::WebContents::CreateWithSessionStorage(
1331 content::WebContents::CreateParams(browser()->profile()),
1332 session_storage_namespace_map));
1334 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1335 scoped_ptr<content::WebContents> old_web_contents(
1336 tab_strip_model->ReplaceWebContentsAt(
1337 tab_strip_model->active_index(), web_contents.release()));
1338 // Navigate with the new tab.
1339 ui_test_utils::NavigateToURL(browser(), url2_);
1340 // old_web_contents goes out of scope.
1343 // Check that the sessionStorage data is going to be persisted.
1344 content::NavigationController* controller =
1345 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1346 EXPECT_TRUE(
1347 controller->GetDefaultSessionStorageNamespace()->should_persist());
1349 // Quit and restore. Check that no extra tabs were created.
1350 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1351 ASSERT_EQ(1u, active_browser_list_->size());
1352 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
1355 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreSimpleTest, CorrectLoadingOrder) {
1356 ASSERT_EQ(SessionRestore::SMART_RESTORE_MODE_SIMPLE,
1357 SessionRestore::GetSmartRestoreMode());
1359 // Start observing the loading of tabs, to make sure the order is correct.
1360 StartObserving(kExpectedNumTabs);
1362 struct TabInfo {
1363 GURL url;
1364 bool pinned;
1365 int expected_load_order;
1368 TabInfo tab_info[kExpectedNumTabs] = {
1369 // This will be the foreground tab and will always load first.
1370 {GURL("http://google.com/1"), false, 1},
1371 {GURL("http://google.com/2"), false, 3},
1372 // Internal page, should load last.
1373 {GURL(chrome::kChromeUINewTabURL), false, 6},
1374 {GURL("http://google.com/4"), false, 4},
1375 {GURL("http://google.com/5"), true, 2}, // Pinned, should load second.
1376 {GURL("http://google.com/6"), false, 5},
1379 // Set up the restore data.
1380 std::vector<const sessions::SessionWindow*> session;
1381 sessions::SessionWindow window;
1382 sessions::SessionTab tab[kExpectedNumTabs];
1384 for (int i = 0; i < kExpectedNumTabs; i++) {
1385 SerializedNavigationEntry nav =
1386 SerializedNavigationEntryTestHelper::CreateNavigation(
1387 tab_info[i].url.spec(), tab_info[i].url.spec().c_str());
1388 sync_pb::SessionTab sync_data;
1389 sync_data.set_tab_visual_index(0);
1390 sync_data.set_current_navigation_index(0);
1391 sync_data.add_navigation()->CopyFrom(nav.ToSyncData());
1392 sync_data.set_pinned(tab_info[i].pinned);
1393 tab[i].SetFromSyncData(sync_data, base::Time::Now());
1394 window.tabs.push_back(tab + i);
1397 session.push_back(&window);
1398 Profile* profile = browser()->profile();
1399 std::vector<Browser*> browsers = SessionRestore::RestoreForeignSessionWindows(
1400 profile, browser()->host_desktop_type(), session.begin(), session.end());
1402 ASSERT_EQ(1u, browsers.size());
1403 ASSERT_TRUE(browsers[0]);
1404 ASSERT_EQ(kExpectedNumTabs, browsers[0]->tab_strip_model()->count());
1406 WaitForAllTabsToStartLoading();
1408 ASSERT_EQ(static_cast<size_t>(kExpectedNumTabs), web_contents().size());
1410 // Make sure that contents are loaded in the correct order, ie. each tab rank
1411 // is higher that its preceding one.
1412 std::map<GURL, int> ranks;
1413 for (auto t : tab_info)
1414 ranks[t.url] = t.expected_load_order;
1415 for (size_t i = 1; i < web_contents().size(); i++) {
1416 int current_rank = ranks[web_contents()[i]->GetLastCommittedURL()];
1417 int previous_rank = ranks[web_contents()[i - 1]->GetLastCommittedURL()];
1418 ASSERT_LT(previous_rank, current_rank);
1421 // The SessionWindow destructor deletes the tabs, so we have to clear them
1422 // here to avoid a crash.
1423 window.tabs.clear();
1426 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreMRUTest, PRE_CorrectLoadingOrder) {
1427 Profile* profile = browser()->profile();
1429 int activation_order[] = {4, 2, 1, 5, 0, 3};
1431 // Replace the first tab and add the other tabs.
1432 ui_test_utils::NavigateToURL(browser(), GURL(kUrls[0]));
1433 for (int i = 1; i < kExpectedNumTabs; i++) {
1434 ui_test_utils::NavigateToURLWithDisposition(
1435 browser(), GURL(kUrls[i]), NEW_FOREGROUND_TAB,
1436 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1439 ASSERT_EQ(kExpectedNumTabs, browser()->tab_strip_model()->count());
1441 // Activate the tabs one by one following the random activation order.
1442 for (auto i : activation_order)
1443 browser()->tab_strip_model()->ActivateTabAt(i, true);
1445 // Close the browser.
1446 g_browser_process->AddRefModule();
1447 CloseBrowserSynchronously(browser());
1449 StartObserving(kExpectedNumTabs);
1451 // Create a new window, which should trigger session restore.
1452 ui_test_utils::BrowserAddedObserver window_observer;
1453 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
1454 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
1455 ASSERT_TRUE(new_browser != NULL);
1456 WaitForAllTabsToStartLoading();
1457 g_browser_process->ReleaseModule();
1459 ASSERT_EQ(static_cast<size_t>(kExpectedNumTabs), web_contents().size());
1460 // Test that we have observed the tabs being loaded in the inverse order of
1461 // their activation (MRU). Also validate that their last active time is in the
1462 // correct order.
1463 for (size_t i = 0; i < web_contents().size(); i++) {
1464 GURL expected_url = GURL(kUrls[activation_order[kExpectedNumTabs - i - 1]]);
1465 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL());
1466 if (i > 0) {
1467 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(),
1468 web_contents()[i]->GetLastActiveTime());
1472 // Activate the 2nd tab before the browser closes. This should be persisted in
1473 // the following test.
1474 new_browser->tab_strip_model()->ActivateTabAt(1, true);
1477 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreMRUTest, CorrectLoadingOrder) {
1478 int activation_order[] = {4, 2, 5, 0, 3, 1};
1479 Profile* profile = browser()->profile();
1481 // Close the browser that gets opened automatically so we can track the order
1482 // of loading of the tabs.
1483 g_browser_process->AddRefModule();
1484 CloseBrowserSynchronously(browser());
1485 // We have an extra tab that is added when the test starts, which gets ignored
1486 // later when we test for proper order.
1487 StartObserving(kExpectedNumTabs + 1);
1489 // Create a new window, which should trigger session restore.
1490 ui_test_utils::BrowserAddedObserver window_observer;
1491 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
1492 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
1493 ASSERT_TRUE(new_browser != NULL);
1494 WaitForAllTabsToStartLoading();
1495 g_browser_process->ReleaseModule();
1497 ASSERT_EQ(static_cast<size_t>(kExpectedNumTabs + 1), web_contents().size());
1499 // Test that we have observed the tabs being loaded in the inverse order of
1500 // their activation (MRU). Also validate that their last active time is in the
1501 // correct order.
1503 // Note that we ignore the first tab as it's an empty one that is added
1504 // automatically at the start of the test.
1505 for (size_t i = 1; i < web_contents().size(); i++) {
1506 GURL expected_url = GURL(kUrls[activation_order[kExpectedNumTabs - i]]);
1507 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL());
1508 if (i > 0) {
1509 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(),
1510 web_contents()[i]->GetLastActiveTime());