[Sync] Rename PSS::IsSyncEnabled to PSS::IsSyncAllowedByFlag.
[chromium-blink-merge.git] / chrome / browser / sessions / session_restore_browsertest.cc
blob647e499a0c9b64aac339c5953acd07816a3b9de9
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/chrome_notification_types.h"
15 #include "chrome/browser/defaults.h"
16 #include "chrome/browser/first_run/first_run.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/sessions/session_restore.h"
20 #include "chrome/browser/sessions/session_restore_test_helper.h"
21 #include "chrome/browser/sessions/session_service.h"
22 #include "chrome/browser/sessions/session_service_factory.h"
23 #include "chrome/browser/sessions/session_service_test_helper.h"
24 #include "chrome/browser/sessions/tab_restore_service.h"
25 #include "chrome/browser/sessions/tab_restore_service_factory.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_commands.h"
28 #include "chrome/browser/ui/browser_list.h"
29 #include "chrome/browser/ui/browser_tabstrip.h"
30 #include "chrome/browser/ui/browser_window.h"
31 #include "chrome/browser/ui/host_desktop.h"
32 #include "chrome/browser/ui/tabs/tab_strip_model.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/url_constants.h"
35 #include "chrome/test/base/in_process_browser_test.h"
36 #include "chrome/test/base/test_switches.h"
37 #include "chrome/test/base/ui_test_utils.h"
38 #include "components/sessions/serialized_navigation_entry_test_helper.h"
39 #include "components/sessions/session_types.h"
40 #include "content/public/browser/navigation_controller.h"
41 #include "content/public/browser/navigation_entry.h"
42 #include "content/public/browser/notification_service.h"
43 #include "content/public/browser/notification_types.h"
44 #include "content/public/browser/render_process_host.h"
45 #include "content/public/browser/render_view_host.h"
46 #include "content/public/browser/web_contents.h"
47 #include "content/public/common/bindings_policy.h"
48 #include "content/public/test/browser_test_utils.h"
49 #include "content/public/test/test_navigation_observer.h"
50 #include "sync/protocol/session_specifics.pb.h"
51 #include "ui/base/page_transition_types.h"
53 using sessions::SerializedNavigationEntry;
54 using sessions::SerializedNavigationEntryTestHelper;
56 #if defined(OS_MACOSX)
57 #include "base/mac/scoped_nsautorelease_pool.h"
58 #endif
60 #if defined(USE_AURA)
61 #include "ui/aura/window.h"
62 #endif
64 class SessionRestoreTest : public InProcessBrowserTest {
65 public:
66 SessionRestoreTest() : active_browser_list_(NULL) {}
68 protected:
69 #if defined(OS_CHROMEOS)
70 void SetUpCommandLine(base::CommandLine* command_line) override {
71 // TODO(nkostylev): Investigate if we can remove this switch.
72 command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests);
73 InProcessBrowserTest::SetUpCommandLine(command_line);
75 #endif
77 void SetUpOnMainThread() override {
78 active_browser_list_ = BrowserList::GetInstance(chrome::GetActiveDesktop());
80 SessionStartupPref pref(SessionStartupPref::LAST);
81 SessionStartupPref::SetStartupPref(browser()->profile(), pref);
82 #if defined(OS_CHROMEOS)
83 const testing::TestInfo* const test_info =
84 testing::UnitTest::GetInstance()->current_test_info();
85 if (strcmp(test_info->name(), "NoSessionRestoreNewWindowChromeOS") != 0) {
86 // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we
87 // can get these test to work without quitting.
88 SessionServiceTestHelper helper(
89 SessionServiceFactory::GetForProfile(browser()->profile()));
90 helper.SetForceBrowserNotAliveWithNoWindows(true);
91 helper.ReleaseService();
93 #endif
95 InProcessBrowserTest::SetUpOnMainThread();
98 bool SetUpUserDataDirectory() override {
99 url1_ = ui_test_utils::GetTestUrl(
100 base::FilePath().AppendASCII("session_history"),
101 base::FilePath().AppendASCII("bot1.html"));
102 url2_ = ui_test_utils::GetTestUrl(
103 base::FilePath().AppendASCII("session_history"),
104 base::FilePath().AppendASCII("bot2.html"));
105 url3_ = ui_test_utils::GetTestUrl(
106 base::FilePath().AppendASCII("session_history"),
107 base::FilePath().AppendASCII("bot3.html"));
109 return InProcessBrowserTest::SetUpUserDataDirectory();
112 void CloseBrowserSynchronously(Browser* browser) {
113 content::WindowedNotificationObserver observer(
114 chrome::NOTIFICATION_BROWSER_CLOSED,
115 content::NotificationService::AllSources());
116 browser->window()->Close();
117 #if defined(OS_MACOSX)
118 // BrowserWindowController depends on the auto release pool being recycled
119 // in the message loop to delete itself, which frees the Browser object
120 // which fires this event.
121 AutoreleasePool()->Recycle();
122 #endif
123 observer.Wait();
126 Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) {
127 return QuitBrowserAndRestoreWithURL(
128 browser, expected_tab_count, GURL(), true);
131 Browser* QuitBrowserAndRestoreWithURL(Browser* browser,
132 int expected_tab_count,
133 const GURL& url,
134 bool no_memory_pressure) {
135 Profile* profile = browser->profile();
137 // Close the browser.
138 g_browser_process->AddRefModule();
139 CloseBrowserSynchronously(browser);
141 // Create a new window, which should trigger session restore.
142 ui_test_utils::BrowserAddedObserver window_observer;
143 SessionRestoreTestHelper restore_observer;
144 if (url.is_empty()) {
145 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
146 } else {
147 chrome::NavigateParams params(profile,
148 url,
149 ui::PAGE_TRANSITION_LINK);
150 chrome::Navigate(&params);
152 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
153 // Stop loading anything more if we are running out of space.
154 if (!no_memory_pressure) {
155 base::MemoryPressureListener::NotifyMemoryPressure(
156 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
158 restore_observer.Wait();
160 if (no_memory_pressure)
161 WaitForTabsToLoad(new_browser);
163 g_browser_process->ReleaseModule();
165 return new_browser;
168 void GoBack(Browser* browser) {
169 content::TestNavigationObserver observer(
170 browser->tab_strip_model()->GetActiveWebContents());
171 chrome::GoBack(browser, CURRENT_TAB);
172 observer.Wait();
175 void GoForward(Browser* browser) {
176 content::TestNavigationObserver observer(
177 browser->tab_strip_model()->GetActiveWebContents());
178 chrome::GoForward(browser, CURRENT_TAB);
179 observer.Wait();
182 void AssertOneWindowWithOneTab(Browser* browser) {
183 ASSERT_EQ(1u, active_browser_list_->size());
184 ASSERT_EQ(1, browser->tab_strip_model()->count());
187 int RenderProcessHostCount() {
188 content::RenderProcessHost::iterator hosts =
189 content::RenderProcessHost::AllHostsIterator();
190 int count = 0;
191 while (!hosts.IsAtEnd()) {
192 if (hosts.GetCurrentValue()->HasConnection())
193 count++;
194 hosts.Advance();
196 return count;
199 void WaitForTabsToLoad(Browser* browser) {
200 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
201 content::WebContents* contents =
202 browser->tab_strip_model()->GetWebContentsAt(i);
203 contents->GetController().LoadIfNecessary();
204 content::WaitForLoadStop(contents);
208 GURL url1_;
209 GURL url2_;
210 GURL url3_;
212 const BrowserList* active_browser_list_;
215 // Activates the smart restore behaviour in "simple" mode and tracks the loading
216 // of tabs.
217 class SmartSessionRestoreSimpleTest : public SessionRestoreTest,
218 public content::NotificationObserver {
219 public:
220 SmartSessionRestoreSimpleTest() {}
221 void StartObserving(int num_tabs) {
222 // Start by clearing everything so it can be reused in the same test.
223 web_contents_.clear();
224 registrar_.RemoveAll();
225 num_tabs_ = num_tabs;
226 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
227 content::NotificationService::AllSources());
229 void Observe(int type,
230 const content::NotificationSource& source,
231 const content::NotificationDetails& details) override {
232 switch (type) {
233 case content::NOTIFICATION_LOAD_START: {
234 content::NavigationController* controller =
235 content::Source<content::NavigationController>(source).ptr();
236 web_contents_.push_back(controller->GetWebContents());
237 if (web_contents_.size() == static_cast<size_t>(num_tabs_))
238 message_loop_runner_->Quit();
239 break;
243 const std::vector<content::WebContents*>& web_contents() const {
244 return web_contents_;
247 void WaitForAllTabsToStartLoading() {
248 message_loop_runner_ = new content::MessageLoopRunner;
249 message_loop_runner_->Run();
252 protected:
253 void SetUpCommandLine(base::CommandLine* command_line) override {
254 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
255 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/");
256 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
257 switches::kForceFieldTrialParams,
258 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/simple");
261 private:
262 content::NotificationRegistrar registrar_;
263 // Ordered by load start order.
264 std::vector<content::WebContents*> web_contents_;
265 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
266 int num_tabs_;
268 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreSimpleTest);
271 class SmartSessionRestoreMRUTest : public SmartSessionRestoreSimpleTest {
272 public:
273 SmartSessionRestoreMRUTest() {}
275 protected:
276 void SetUpCommandLine(base::CommandLine* command_line) override {
277 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
278 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/");
279 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
280 switches::kForceFieldTrialParams,
281 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/mru");
284 private:
285 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreMRUTest);
288 // Verifies that restored tabs have a root window. This is important
289 // otherwise the wrong information is communicated to the renderer.
290 // (http://crbug.com/342672).
291 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveWindow) {
292 // Create tabs.
293 ui_test_utils::NavigateToURLWithDisposition(
294 browser(),
295 GURL(url::kAboutBlankURL),
296 NEW_FOREGROUND_TAB,
297 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
298 ui_test_utils::NavigateToURLWithDisposition(
299 browser(),
300 GURL(url::kAboutBlankURL),
301 NEW_BACKGROUND_TAB,
302 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
304 // Restart and session restore the tabs.
305 Browser* restored = QuitBrowserAndRestore(browser(), 3);
306 TabStripModel* tab_strip_model = restored->tab_strip_model();
307 const int tabs = tab_strip_model->count();
308 ASSERT_EQ(3, tabs);
310 // Check the restored tabs have a window to get screen info from.
311 // On Aura it should also have a root window.
312 for (int i = 0; i < tabs; ++i) {
313 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
314 EXPECT_TRUE(contents->GetTopLevelNativeWindow());
315 #if defined(USE_AURA)
316 EXPECT_TRUE(contents->GetNativeView()->GetRootWindow());
317 #endif
321 // Verify that restored tabs have correct disposition. Only one tab should
322 // have "visible" visibility state, the rest should not.
323 // (http://crbug.com/155365 http://crbug.com/118269)
324 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
325 RestoredTabsHaveCorrectVisibilityState) {
326 // Create tabs.
327 GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(),
328 base::FilePath(FILE_PATH_LITERAL("tab-restore-visibilty.html"))));
329 ui_test_utils::NavigateToURLWithDisposition(
330 browser(), test_page, NEW_FOREGROUND_TAB,
331 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
332 ui_test_utils::NavigateToURLWithDisposition(
333 browser(), test_page, NEW_BACKGROUND_TAB,
334 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
336 // Restart and session restore the tabs.
337 content::DOMMessageQueue message_queue;
338 Browser* restored = QuitBrowserAndRestore(browser(), 3);
339 for (int i = 0; i < 2; ++i) {
340 std::string message;
341 EXPECT_TRUE(message_queue.WaitForMessage(&message));
342 EXPECT_EQ("\"READY\"", message);
345 // There should be 3 restored tabs in the new browser.
346 TabStripModel* tab_strip_model = restored->tab_strip_model();
347 const int tabs = tab_strip_model->count();
348 ASSERT_EQ(3, tabs);
350 // The middle tab only should have visible disposition.
351 for (int i = 0; i < tabs; ++i) {
352 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
353 std::string document_visibility_state;
354 const char kGetStateJS[] = "window.domAutomationController.send("
355 "window.document.visibilityState);";
356 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
357 contents, kGetStateJS, &document_visibility_state));
358 if (i == 1) {
359 EXPECT_EQ("visible", document_visibility_state);
360 } else {
361 EXPECT_EQ("hidden", document_visibility_state);
366 #if defined(OS_CHROMEOS)
367 // Verify that session restore does not occur when a user opens a browser window
368 // when no other browser windows are open on ChromeOS.
369 // TODO(pkotwicz): Add test which doesn't open incognito browser once
370 // disable-zero-browsers-open-for-tests is removed.
371 // (http://crbug.com/119175)
372 // TODO(pkotwicz): Mac should have the behavior outlined by this test. It should
373 // not do session restore if an incognito window is already open.
374 // (http://crbug.com/120927)
375 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) {
376 GURL url(ui_test_utils::GetTestUrl(
377 base::FilePath(base::FilePath::kCurrentDirectory),
378 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
380 // Add a single tab.
381 ui_test_utils::NavigateToURL(browser(), url);
383 Browser* incognito_browser = CreateIncognitoBrowser();
384 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
385 incognito_browser->window()->Show();
387 // Close the normal browser. After this we only have the incognito window
388 // open.
389 CloseBrowserSynchronously(browser());
391 // Create a new window, which should open NTP.
392 ui_test_utils::BrowserAddedObserver browser_added_observer;
393 chrome::NewWindow(incognito_browser);
394 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
396 ASSERT_TRUE(new_browser);
397 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
398 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
399 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
402 // Test that maximized applications get restored maximized.
403 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MaximizedApps) {
404 const char* app_name = "TestApp";
405 Browser* app_browser = CreateBrowserForApp(app_name, browser()->profile());
406 app_browser->window()->Maximize();
407 app_browser->window()->Show();
408 EXPECT_TRUE(app_browser->window()->IsMaximized());
409 EXPECT_TRUE(app_browser->is_app());
410 EXPECT_TRUE(app_browser->is_type_popup());
412 // Close the normal browser. After this we only have the app_browser window.
413 CloseBrowserSynchronously(browser());
415 // Create a new window, which should open NTP.
416 ui_test_utils::BrowserAddedObserver browser_added_observer;
417 chrome::NewWindow(app_browser);
418 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
420 ASSERT_TRUE(new_browser);
421 EXPECT_TRUE(app_browser->window()->IsMaximized());
422 EXPECT_TRUE(app_browser->is_app());
423 EXPECT_TRUE(app_browser->is_type_popup());
425 #endif // OS_CHROMEOS
427 #if !defined(OS_CHROMEOS)
428 // This test does not apply to ChromeOS as it does not do session restore when
429 // a new window is opened.
431 #if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
432 // Crashes on Linux Views: http://crbug.com/39476
433 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
434 DISABLED_RestoreOnNewWindowWithNoTabbedBrowsers
435 #else
436 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
437 RestoreOnNewWindowWithNoTabbedBrowsers
438 #endif
440 // Makes sure when session restore is triggered in the same process we don't end
441 // up with an extra tab.
442 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
443 MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers) {
444 const base::FilePath::CharType* kTitle1File =
445 FILE_PATH_LITERAL("title1.html");
446 GURL url(ui_test_utils::GetTestUrl(base::FilePath(
447 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
448 ui_test_utils::NavigateToURL(browser(), url);
450 // Turn on session restore.
451 SessionStartupPref::SetStartupPref(
452 browser()->profile(),
453 SessionStartupPref(SessionStartupPref::LAST));
455 // Create a new popup.
456 Profile* profile = browser()->profile();
457 Browser* popup =
458 new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile,
459 browser()->host_desktop_type()));
460 popup->window()->Show();
462 // Close the browser.
463 CloseBrowserSynchronously(browser());
465 // Create a new window, which should trigger session restore.
466 ui_test_utils::BrowserAddedObserver observer;
467 chrome::NewWindow(popup);
468 Browser* new_browser = observer.WaitForSingleNewBrowser();
470 ASSERT_TRUE(new_browser != NULL);
472 // The browser should only have one tab.
473 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
475 // And the first url should be url.
476 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
478 #endif // !OS_CHROMEOS
480 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreIndividualTabFromWindow) {
481 GURL url1(ui_test_utils::GetTestUrl(
482 base::FilePath(base::FilePath::kCurrentDirectory),
483 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
484 // Any page that will yield a 200 status code will work here.
485 GURL url2("chrome://version");
486 GURL url3(ui_test_utils::GetTestUrl(
487 base::FilePath(base::FilePath::kCurrentDirectory),
488 base::FilePath(FILE_PATH_LITERAL("title3.html"))));
490 // Add and navigate three tabs.
491 ui_test_utils::NavigateToURL(browser(), url1);
493 content::WindowedNotificationObserver observer(
494 content::NOTIFICATION_LOAD_STOP,
495 content::NotificationService::AllSources());
496 chrome::AddSelectedTabWithURL(browser(), url2,
497 ui::PAGE_TRANSITION_LINK);
498 observer.Wait();
501 content::WindowedNotificationObserver observer(
502 content::NOTIFICATION_LOAD_STOP,
503 content::NotificationService::AllSources());
504 chrome::AddSelectedTabWithURL(browser(), url3,
505 ui::PAGE_TRANSITION_LINK);
506 observer.Wait();
509 TabRestoreService* service =
510 TabRestoreServiceFactory::GetForProfile(browser()->profile());
511 service->ClearEntries();
513 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
515 browser()->window()->Close();
517 // Expect a window with three tabs.
518 ASSERT_EQ(1U, service->entries().size());
519 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
520 const TabRestoreService::Window* window =
521 static_cast<TabRestoreService::Window*>(service->entries().front());
522 EXPECT_EQ(3U, window->tabs.size());
524 // Find the SessionID for entry2. Since the session service was destroyed,
525 // there is no guarantee that the SessionID for the tab has remained the same.
526 base::Time timestamp;
527 int http_status_code = 0;
528 for (std::vector<TabRestoreService::Tab>::const_iterator it =
529 window->tabs.begin(); it != window->tabs.end(); ++it) {
530 const TabRestoreService::Tab& tab = *it;
531 // If this tab held url2, then restore this single tab.
532 if (tab.navigations[0].virtual_url() == url2) {
533 timestamp = tab.navigations[0].timestamp();
534 http_status_code = tab.navigations[0].http_status_code();
535 std::vector<content::WebContents*> content =
536 service->RestoreEntryById(NULL, tab.id, host_desktop_type, UNKNOWN);
537 ASSERT_EQ(1U, content.size());
538 ASSERT_TRUE(content[0]);
539 EXPECT_EQ(url2, content[0]->GetURL());
540 break;
543 EXPECT_FALSE(timestamp.is_null());
544 EXPECT_EQ(200, http_status_code);
546 // Make sure that the restored tab is removed from the service.
547 ASSERT_EQ(1U, service->entries().size());
548 ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
549 window = static_cast<TabRestoreService::Window*>(service->entries().front());
550 EXPECT_EQ(2U, window->tabs.size());
552 // Make sure that the restored tab was restored with the correct
553 // timestamp and status code.
554 const content::WebContents* contents =
555 browser()->tab_strip_model()->GetActiveWebContents();
556 ASSERT_TRUE(contents);
557 const content::NavigationEntry* entry =
558 contents->GetController().GetActiveEntry();
559 ASSERT_TRUE(entry);
560 EXPECT_EQ(timestamp, entry->GetTimestamp());
561 EXPECT_EQ(http_status_code, entry->GetHttpStatusCode());
564 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) {
565 GURL url(ui_test_utils::GetTestUrl(
566 base::FilePath(base::FilePath::kCurrentDirectory),
567 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
569 // Add a single tab.
570 ui_test_utils::NavigateToURL(browser(), url);
572 TabRestoreService* service =
573 TabRestoreServiceFactory::GetForProfile(browser()->profile());
574 service->ClearEntries();
575 EXPECT_EQ(0U, service->entries().size());
577 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
579 // Close the window.
580 browser()->window()->Close();
582 // Expect the window to be converted to a tab by the TRS.
583 EXPECT_EQ(1U, service->entries().size());
584 ASSERT_EQ(TabRestoreService::TAB, service->entries().front()->type);
585 const TabRestoreService::Tab* tab =
586 static_cast<TabRestoreService::Tab*>(service->entries().front());
588 // Restore the tab.
589 std::vector<content::WebContents*> content =
590 service->RestoreEntryById(NULL, tab->id, host_desktop_type, UNKNOWN);
591 ASSERT_EQ(1U, content.size());
592 ASSERT_TRUE(content[0]);
593 EXPECT_EQ(url, content[0]->GetURL());
595 // Make sure the restore was successful.
596 EXPECT_EQ(0U, service->entries().size());
599 #if !defined(OS_CHROMEOS)
600 // This test does not apply to ChromeOS as ChromeOS does not do session
601 // restore when a new window is open.
603 // Verifies we remember the last browser window when closing the last
604 // non-incognito window while an incognito window is open.
605 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) {
606 GURL url(ui_test_utils::GetTestUrl(
607 base::FilePath(base::FilePath::kCurrentDirectory),
608 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
610 // Add a single tab.
611 ui_test_utils::NavigateToURL(browser(), url);
613 // Create a new incognito window.
614 Browser* incognito_browser = CreateIncognitoBrowser();
615 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
616 incognito_browser->window()->Show();
618 // Close the normal browser. After this we only have the incognito window
619 // open.
620 CloseBrowserSynchronously(browser());
622 // Create a new window, which should trigger session restore.
623 ui_test_utils::BrowserAddedObserver browser_added_observer;
624 chrome::NewWindow(incognito_browser);
625 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
627 // The first tab should have 'url' as its url.
628 ASSERT_TRUE(new_browser);
629 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
631 #endif // !OS_CHROMEOS
633 namespace {
635 // Verifies that the given NavigationController has exactly two
636 // entries that correspond to the given URLs and that all but the last
637 // entry have null timestamps.
638 void VerifyNavigationEntries(
639 const content::NavigationController& controller,
640 GURL url1, GURL url2) {
641 ASSERT_EQ(2, controller.GetEntryCount());
642 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
643 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
644 EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL());
645 EXPECT_TRUE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
646 EXPECT_FALSE(controller.GetEntryAtIndex(1)->GetTimestamp().is_null());
649 } // namespace
651 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) {
652 GURL url1("http://google.com");
653 GURL url2("http://google2.com");
654 SerializedNavigationEntry nav1 =
655 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
656 SerializedNavigationEntry nav2 =
657 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
659 // Set up the restore data.
660 sync_pb::SessionTab sync_data;
661 sync_data.set_tab_visual_index(0);
662 sync_data.set_current_navigation_index(1);
663 sync_data.set_pinned(false);
664 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
665 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
667 sessions::SessionTab tab;
668 tab.SetFromSyncData(sync_data, base::Time::Now());
669 EXPECT_EQ(2U, tab.navigations.size());
670 for (size_t i = 0; i < tab.navigations.size(); ++i)
671 EXPECT_TRUE(tab.navigations[i].timestamp().is_null());
673 ASSERT_EQ(1, browser()->tab_strip_model()->count());
675 // Restore in the current tab.
676 content::WebContents* tab_content = NULL;
678 content::WindowedNotificationObserver observer(
679 content::NOTIFICATION_LOAD_STOP,
680 content::NotificationService::AllSources());
681 tab_content = SessionRestore::RestoreForeignSessionTab(
682 browser()->tab_strip_model()->GetActiveWebContents(), tab, CURRENT_TAB);
683 observer.Wait();
685 ASSERT_EQ(1, browser()->tab_strip_model()->count());
686 content::WebContents* web_contents =
687 browser()->tab_strip_model()->GetWebContentsAt(0);
688 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
689 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
690 ASSERT_TRUE(tab_content);
691 ASSERT_EQ(url2, tab_content->GetURL());
693 // Restore in a new tab.
694 tab_content = NULL;
696 content::WindowedNotificationObserver observer(
697 content::NOTIFICATION_LOAD_STOP,
698 content::NotificationService::AllSources());
699 tab_content = SessionRestore::RestoreForeignSessionTab(
700 browser()->tab_strip_model()->GetActiveWebContents(),
701 tab, NEW_BACKGROUND_TAB);
702 observer.Wait();
704 ASSERT_EQ(2, browser()->tab_strip_model()->count());
705 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
706 web_contents = browser()->tab_strip_model()->GetWebContentsAt(1);
707 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
708 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
709 ASSERT_TRUE(tab_content);
710 ASSERT_EQ(url2, tab_content->GetURL());
712 // Restore in a new window.
713 Browser* new_browser = NULL;
714 tab_content = NULL;
716 ui_test_utils::BrowserAddedObserver browser_observer;
717 content::WindowedNotificationObserver observer(
718 content::NOTIFICATION_LOAD_STOP,
719 content::NotificationService::AllSources());
720 tab_content = SessionRestore::RestoreForeignSessionTab(
721 browser()->tab_strip_model()->GetActiveWebContents(), tab, NEW_WINDOW);
722 new_browser = browser_observer.WaitForSingleNewBrowser();
723 observer.Wait();
726 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
727 web_contents = new_browser->tab_strip_model()->GetWebContentsAt(0);
728 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
729 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
730 ASSERT_TRUE(tab_content);
731 ASSERT_EQ(url2, tab_content->GetURL());
734 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) {
735 Profile* profile = browser()->profile();
737 GURL url1("http://google.com");
738 GURL url2("http://google2.com");
739 SerializedNavigationEntry nav1 =
740 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
741 SerializedNavigationEntry nav2 =
742 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
743 SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav2);
745 // Set up the restore data -- one window with two tabs.
746 std::vector<const sessions::SessionWindow*> session;
747 sessions::SessionWindow window;
748 sessions::SessionTab tab1;
750 sync_pb::SessionTab sync_data;
751 sync_data.set_tab_visual_index(0);
752 sync_data.set_current_navigation_index(0);
753 sync_data.set_pinned(true);
754 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
755 tab1.SetFromSyncData(sync_data, base::Time::Now());
757 window.tabs.push_back(&tab1);
759 sessions::SessionTab tab2;
761 sync_pb::SessionTab sync_data;
762 sync_data.set_tab_visual_index(1);
763 sync_data.set_current_navigation_index(0);
764 sync_data.set_pinned(false);
765 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
766 tab2.SetFromSyncData(sync_data, base::Time::Now());
768 window.tabs.push_back(&tab2);
770 // Leave tab3 empty. Should have no effect on restored session, but simulates
771 // partially complete foreign session data.
772 sessions::SessionTab tab3;
773 window.tabs.push_back(&tab3);
775 session.push_back(static_cast<const sessions::SessionWindow*>(&window));
776 ui_test_utils::BrowserAddedObserver window_observer;
777 std::vector<Browser*> browsers =
778 SessionRestore::RestoreForeignSessionWindows(
779 profile, browser()->host_desktop_type(), session.begin(),
780 session.end());
781 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
782 ASSERT_TRUE(new_browser);
783 ASSERT_EQ(2u, active_browser_list_->size());
784 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
786 ASSERT_EQ(1u, browsers.size());
787 ASSERT_TRUE(browsers[0]);
788 ASSERT_EQ(2, browsers[0]->tab_strip_model()->count());
790 content::WebContents* web_contents_1 =
791 new_browser->tab_strip_model()->GetWebContentsAt(0);
792 content::WebContents* web_contents_2 =
793 new_browser->tab_strip_model()->GetWebContentsAt(1);
794 ASSERT_EQ(url1, web_contents_1->GetURL());
795 ASSERT_EQ(url2, web_contents_2->GetURL());
797 // Check user agent override state.
798 ASSERT_TRUE(web_contents_1->GetUserAgentOverride().empty());
799 ASSERT_TRUE(web_contents_2->GetUserAgentOverride().empty());
801 content::NavigationEntry* entry =
802 web_contents_1->GetController().GetActiveEntry();
803 ASSERT_TRUE(entry);
804 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
806 entry = web_contents_2->GetController().GetActiveEntry();
807 ASSERT_TRUE(entry);
808 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
810 // The SessionWindow destructor deletes the tabs, so we have to clear them
811 // here to avoid a crash.
812 window.tabs.clear();
815 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) {
816 ui_test_utils::NavigateToURL(browser(), url1_);
817 ui_test_utils::NavigateToURL(browser(), url2_);
819 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
820 ASSERT_EQ(1u, active_browser_list_->size());
821 ASSERT_EQ(url2_,
822 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
823 GoBack(new_browser);
824 ASSERT_EQ(url1_,
825 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
828 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoMemoryPressureLoadsAllTabs) {
829 // Add several tabs to the browser. Restart the browser and check that all
830 // tabs got loaded properly.
831 ui_test_utils::NavigateToURLWithDisposition(
832 browser(),
833 GURL(url::kAboutBlankURL),
834 NEW_FOREGROUND_TAB,
835 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
836 ui_test_utils::NavigateToURLWithDisposition(
837 browser(),
838 GURL(url::kAboutBlankURL),
839 NEW_FOREGROUND_TAB,
840 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
841 Browser* restored =
842 QuitBrowserAndRestoreWithURL(browser(), 1, GURL(), true);
843 TabStripModel* tab_strip_model = restored->tab_strip_model();
845 ASSERT_EQ(1u, active_browser_list_->size());
847 ASSERT_EQ(3, tab_strip_model->count());
848 // All render widgets should be initialized by now.
849 ASSERT_TRUE(
850 tab_strip_model->GetWebContentsAt(0)->GetRenderWidgetHostView() &&
851 tab_strip_model->GetWebContentsAt(1)->GetRenderWidgetHostView() &&
852 tab_strip_model->GetWebContentsAt(2)->GetRenderWidgetHostView());
855 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MemoryPressureLoadsNotAllTabs) {
856 // Add several tabs to the browser. Restart the browser and check that all
857 // tabs got loaded properly.
858 ui_test_utils::NavigateToURLWithDisposition(
859 browser(),
860 GURL(url::kAboutBlankURL),
861 NEW_FOREGROUND_TAB,
862 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
863 ui_test_utils::NavigateToURLWithDisposition(
864 browser(),
865 GURL(url::kAboutBlankURL),
866 NEW_FOREGROUND_TAB,
867 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
868 // Restore the brwoser, but instead of directly waiting, we issue a critical
869 // memory pressure event and finish then the loading.
870 Browser* restored =
871 QuitBrowserAndRestoreWithURL(browser(), 1, GURL(), false);
873 TabStripModel* tab_strip_model = restored->tab_strip_model();
875 ASSERT_EQ(1u, active_browser_list_->size());
877 ASSERT_EQ(3, tab_strip_model->count());
878 // At least one of the render widgets should not be initialized yet.
879 ASSERT_FALSE(
880 tab_strip_model->GetWebContentsAt(0)->GetRenderWidgetHostView() &&
881 tab_strip_model->GetWebContentsAt(1)->GetRenderWidgetHostView() &&
882 tab_strip_model->GetWebContentsAt(2)->GetRenderWidgetHostView());
885 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) {
886 const GURL webui_url("chrome://omnibox");
887 ui_test_utils::NavigateToURL(browser(), webui_url);
888 const content::WebContents* old_tab =
889 browser()->tab_strip_model()->GetActiveWebContents();
890 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
891 old_tab->GetRenderViewHost()->GetEnabledBindings());
893 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
894 ASSERT_EQ(1u, active_browser_list_->size());
895 const content::WebContents* new_tab =
896 new_browser->tab_strip_model()->GetActiveWebContents();
897 EXPECT_EQ(webui_url, new_tab->GetURL());
898 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
899 new_tab->GetRenderViewHost()->GetEnabledBindings());
902 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUISettings) {
903 const GURL webui_url("chrome://settings");
904 ui_test_utils::NavigateToURL(browser(), webui_url);
905 const content::WebContents* old_tab =
906 browser()->tab_strip_model()->GetActiveWebContents();
907 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
908 old_tab->GetRenderViewHost()->GetEnabledBindings());
910 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
911 ASSERT_EQ(1u, active_browser_list_->size());
912 const content::WebContents* new_tab =
913 new_browser->tab_strip_model()->GetActiveWebContents();
914 EXPECT_EQ(webui_url, new_tab->GetURL());
915 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
916 new_tab->GetRenderViewHost()->GetEnabledBindings());
919 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) {
920 ui_test_utils::NavigateToURL(browser(), url1_);
921 ui_test_utils::NavigateToURL(browser(), url2_);
922 ui_test_utils::NavigateToURL(browser(), url3_);
924 GoBack(browser());
925 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
926 ASSERT_EQ(1u, active_browser_list_->size());
927 ASSERT_EQ(url2_,
928 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
929 GoForward(new_browser);
930 ASSERT_EQ(url3_,
931 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
932 GoBack(new_browser);
933 ASSERT_EQ(url2_,
934 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
936 // Test renderer-initiated back/forward as well.
937 GURL go_back_url("javascript:history.back();");
938 ui_test_utils::NavigateToURL(new_browser, go_back_url);
939 ASSERT_EQ(url1_,
940 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
943 // Tests that the SiteInstances used for entries in a restored tab's history
944 // are given appropriate max page IDs, so that going back to a restored
945 // cross-site page and then forward again works. (Bug 1204135)
946 // This test fails. See http://crbug.com/237497.
947 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
948 DISABLED_RestoresCrossSiteForwardAndBackwardNavs) {
949 ASSERT_TRUE(test_server()->Start());
951 GURL cross_site_url(test_server()->GetURL("files/title2.html"));
953 // Visit URLs on different sites.
954 ui_test_utils::NavigateToURL(browser(), url1_);
955 ui_test_utils::NavigateToURL(browser(), cross_site_url);
956 ui_test_utils::NavigateToURL(browser(), url2_);
958 GoBack(browser());
959 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
960 ASSERT_EQ(1u, active_browser_list_->size());
961 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
963 // Check that back and forward work as expected.
964 ASSERT_EQ(cross_site_url,
965 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
967 GoBack(new_browser);
968 ASSERT_EQ(url1_,
969 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
971 GoForward(new_browser);
972 ASSERT_EQ(cross_site_url,
973 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
975 // Test renderer-initiated back/forward as well.
976 GURL go_forward_url("javascript:history.forward();");
977 ui_test_utils::NavigateToURL(new_browser, go_forward_url);
978 ASSERT_EQ(url2_,
979 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
982 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) {
983 ui_test_utils::NavigateToURL(browser(), url1_);
985 ui_test_utils::NavigateToURLWithDisposition(
986 browser(), url2_, NEW_FOREGROUND_TAB,
987 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
989 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
991 ASSERT_EQ(1u, active_browser_list_->size());
992 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
993 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
994 ASSERT_EQ(url2_,
995 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
997 ASSERT_EQ(url1_,
998 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
1001 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
1002 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) {
1003 ui_test_utils::NavigateToURL(browser(), url1_);
1005 ui_test_utils::NavigateToURLWithDisposition(
1006 browser(), url2_, NEW_FOREGROUND_TAB,
1007 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1008 chrome::CloseTab(browser());
1010 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1012 AssertOneWindowWithOneTab(new_browser);
1013 ASSERT_EQ(url1_,
1014 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1017 // Ensures active tab properly restored when tabs before it closed.
1018 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtClose) {
1019 ui_test_utils::NavigateToURL(browser(), url1_);
1020 ui_test_utils::NavigateToURLWithDisposition(
1021 browser(), url2_, NEW_FOREGROUND_TAB,
1022 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1023 ui_test_utils::NavigateToURLWithDisposition(
1024 browser(), url3_, NEW_BACKGROUND_TAB,
1025 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1027 browser()->tab_strip_model()->CloseWebContentsAt(
1029 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
1031 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
1033 ASSERT_EQ(url2_,
1034 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1035 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 0);
1038 // Ensures active tab properly restored when tabs are inserted before it .
1039 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtInsert) {
1040 ui_test_utils::NavigateToURL(browser(), url1_);
1041 ui_test_utils::NavigateToURLWithDisposition(
1042 browser(), url2_, NEW_BACKGROUND_TAB,
1043 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1045 chrome::NavigateParams navigate_params(browser(), url3_,
1046 ui::PAGE_TRANSITION_TYPED);
1047 navigate_params.tabstrip_index = 0;
1048 navigate_params.disposition = NEW_BACKGROUND_TAB;
1049 ui_test_utils::NavigateToURL(&navigate_params);
1051 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
1053 ASSERT_EQ(url1_,
1054 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1055 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1);
1058 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
1059 // This test doesn't apply to the Mac version; see GetCommandLineForRelaunch
1060 // for details. It was disabled for a long time so might never have worked on
1061 // ChromeOS.
1063 // Launches an app window, closes tabbed browser, launches and makes sure
1064 // we restore the tabbed browser url.
1065 // If this test flakes, use http://crbug.com/29110
1066 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
1067 RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
1068 #if defined(OS_WIN) && defined(USE_ASH)
1069 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1070 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1071 switches::kAshBrowserTests))
1072 return;
1073 #endif
1075 ui_test_utils::NavigateToURL(browser(), url1_);
1077 // Launch an app.
1078 base::CommandLine app_launch_arguments = GetCommandLineForRelaunch();
1079 app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
1081 ui_test_utils::BrowserAddedObserver window_observer;
1083 base::LaunchProcess(app_launch_arguments, base::LaunchOptionsForTest());
1085 Browser* app_window = window_observer.WaitForSingleNewBrowser();
1086 ASSERT_EQ(2u, active_browser_list_->size());
1088 // Close the first window. The only window left is the App window.
1089 CloseBrowserSynchronously(browser());
1091 // Restore the session, which should bring back the first window with url1_.
1092 Browser* new_browser = QuitBrowserAndRestore(app_window, 1);
1094 AssertOneWindowWithOneTab(new_browser);
1096 ASSERT_EQ(url1_,
1097 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1100 #endif // !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
1102 // Creates two windows, closes one, restores, make sure only one window open.
1103 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) {
1104 ui_test_utils::NavigateToURL(browser(), url1_);
1106 // Open a second window.
1107 ui_test_utils::NavigateToURLWithDisposition(
1108 browser(),
1109 GURL(url::kAboutBlankURL),
1110 NEW_WINDOW,
1111 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
1113 ASSERT_EQ(2u, active_browser_list_->size());
1115 // Close it.
1116 Browser* new_window = active_browser_list_->get(1);
1117 CloseBrowserSynchronously(new_window);
1119 // Restart and make sure we have only one window with one tab and the url
1120 // is url1_.
1121 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1123 AssertOneWindowWithOneTab(new_browser);
1125 ASSERT_EQ(url1_,
1126 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1129 // Make sure after a restore the number of processes matches that of the number
1130 // of processes running before the restore. This creates a new tab so that
1131 // we should have two new tabs running. (This test will pass in both
1132 // process-per-site and process-per-site-instance, because we treat the new tab
1133 // as a special case in process-per-site-instance so that it only ever uses one
1134 // process.)
1136 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
1137 // Unfortunately, the fix at http://codereview.chromium.org/6546078
1138 // breaks NTP background image refreshing, so ThemeSource had to revert to
1139 // replacing the existing data source.
1140 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) {
1141 // Create two new tabs.
1142 ui_test_utils::NavigateToURLWithDisposition(
1143 browser(),
1144 GURL(url::kAboutBlankURL),
1145 NEW_FOREGROUND_TAB,
1146 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1147 ui_test_utils::NavigateToURLWithDisposition(
1148 browser(),
1149 GURL(url::kAboutBlankURL),
1150 NEW_FOREGROUND_TAB,
1151 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1153 int expected_process_count = RenderProcessHostCount();
1155 // Restart.
1156 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
1158 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1160 ASSERT_EQ(expected_process_count, RenderProcessHostCount());
1163 // Test that changing the user agent override will persist it to disk.
1164 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, PersistAndRestoreUserAgentOverride) {
1165 // Create a tab with an overridden user agent.
1166 ui_test_utils::NavigateToURL(browser(), url1_);
1167 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1168 browser()->tab_strip_model()->GetWebContentsAt(0)->
1169 SetUserAgentOverride("override");
1171 // Create a tab without an overridden user agent.
1172 ui_test_utils::NavigateToURLWithDisposition(
1173 browser(), url2_, NEW_FOREGROUND_TAB,
1174 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1175 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1177 // Kill the original browser then open a new one to trigger a restore.
1178 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1179 ASSERT_EQ(1u, active_browser_list_->size());
1180 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1181 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1183 // Confirm that the user agent overrides are properly set.
1184 EXPECT_EQ("override",
1185 new_browser->tab_strip_model()->GetWebContentsAt(0)->
1186 GetUserAgentOverride());
1187 EXPECT_EQ("",
1188 new_browser->tab_strip_model()->GetWebContentsAt(1)->
1189 GetUserAgentOverride());
1192 // Regression test for crbug.com/125958. When restoring a pinned selected tab in
1193 // a setting where there are existing tabs, the selected index computation was
1194 // wrong, leading to the wrong tab getting selected, DCHECKs firing, and the
1195 // pinned tab not getting loaded.
1196 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestorePinnedSelectedTab) {
1197 // Create a pinned tab.
1198 ui_test_utils::NavigateToURL(browser(), url1_);
1199 browser()->tab_strip_model()->SetTabPinned(0, true);
1200 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1201 // Create a nonpinned tab.
1202 ui_test_utils::NavigateToURLWithDisposition(
1203 browser(), url2_, NEW_FOREGROUND_TAB,
1204 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1205 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1206 // Select the pinned tab.
1207 browser()->tab_strip_model()->ActivateTabAt(0, true);
1208 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1209 Profile* profile = browser()->profile();
1211 // This will also initiate a session restore, but we're not interested in it.
1212 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1213 ASSERT_EQ(1u, active_browser_list_->size());
1214 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1215 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1216 // Close the pinned tab.
1217 chrome::CloseTab(new_browser);
1218 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1219 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1220 // Use the existing tab to navigate away, so that we can verify it was really
1221 // clobbered.
1222 ui_test_utils::NavigateToURL(new_browser, url3_);
1224 // Restore the session again, clobbering the existing tab.
1225 SessionRestore::RestoreSession(
1226 profile, new_browser,
1227 new_browser->host_desktop_type(),
1228 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1229 std::vector<GURL>());
1231 // The pinned tab is the selected tab.
1232 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1233 EXPECT_EQ(0, new_browser->tab_strip_model()->active_index());
1234 EXPECT_EQ(url1_,
1235 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1236 EXPECT_EQ(url2_,
1237 new_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL());
1240 // Regression test for crbug.com/240156. When restoring tabs with a navigation,
1241 // the navigation should take active tab focus.
1242 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWithNavigateSelectedTab) {
1243 // Create 2 tabs.
1244 ui_test_utils::NavigateToURL(browser(), url1_);
1245 ui_test_utils::NavigateToURLWithDisposition(
1246 browser(), url2_, NEW_FOREGROUND_TAB,
1247 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1249 // Restore the session by calling chrome::Navigate().
1250 Browser* new_browser =
1251 QuitBrowserAndRestoreWithURL(browser(), 3, url3_, true);
1252 ASSERT_EQ(1u, active_browser_list_->size());
1253 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1254 // Navigated url should be the active tab.
1255 ASSERT_EQ(url3_,
1256 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1259 // Do a clobber restore from the new tab page. This test follows the code path
1260 // of a crash followed by the user clicking restore from the new tab page.
1261 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClobberRestoreTest) {
1262 // Create 2 tabs.
1263 ui_test_utils::NavigateToURL(browser(), url1_);
1264 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1265 ui_test_utils::NavigateToURLWithDisposition(
1266 browser(), url2_, NEW_FOREGROUND_TAB,
1267 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1268 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1269 Profile* profile = browser()->profile();
1271 // This will also initiate a session restore, but we're not interested in it.
1272 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1273 ASSERT_EQ(1u, active_browser_list_->size());
1274 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1275 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1276 // Close the first tab.
1277 chrome::CloseTab(new_browser);
1278 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1279 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1280 // Use the existing tab to navigate to the NTP.
1281 ui_test_utils::NavigateToURL(new_browser, GURL(chrome::kChromeUINewTabURL));
1283 // Restore the session again, clobbering the existing tab.
1284 SessionRestore::RestoreSession(
1285 profile, new_browser,
1286 new_browser->host_desktop_type(),
1287 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1288 std::vector<GURL>());
1290 // 2 tabs should have been restored, with the existing tab clobbered, giving
1291 // us a total of 2 tabs.
1292 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1293 EXPECT_EQ(1, new_browser->tab_strip_model()->active_index());
1294 EXPECT_EQ(url1_,
1295 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
1296 EXPECT_EQ(url2_,
1297 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1300 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) {
1301 ui_test_utils::NavigateToURL(browser(), url1_);
1302 content::NavigationController* controller =
1303 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1304 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1305 std::string session_storage_persistent_id =
1306 controller->GetDefaultSessionStorageNamespace()->persistent_id();
1307 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1308 ASSERT_EQ(1u, active_browser_list_->size());
1309 ASSERT_EQ(url1_,
1310 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1311 content::NavigationController* new_controller =
1312 &new_browser->tab_strip_model()->GetActiveWebContents()->GetController();
1313 ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace());
1314 std::string restored_session_storage_persistent_id =
1315 new_controller->GetDefaultSessionStorageNamespace()->persistent_id();
1316 EXPECT_EQ(session_storage_persistent_id,
1317 restored_session_storage_persistent_id);
1320 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) {
1321 // Simulate what prerendering does: create a new WebContents with the same
1322 // SessionStorageNamespace as an existing tab, then replace the tab with it.
1324 content::NavigationController* controller =
1325 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1326 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1328 content::SessionStorageNamespaceMap session_storage_namespace_map;
1329 session_storage_namespace_map[std::string()] =
1330 controller->GetDefaultSessionStorageNamespace();
1331 scoped_ptr<content::WebContents> web_contents(
1332 content::WebContents::CreateWithSessionStorage(
1333 content::WebContents::CreateParams(browser()->profile()),
1334 session_storage_namespace_map));
1336 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1337 scoped_ptr<content::WebContents> old_web_contents(
1338 tab_strip_model->ReplaceWebContentsAt(
1339 tab_strip_model->active_index(), web_contents.release()));
1340 // Navigate with the new tab.
1341 ui_test_utils::NavigateToURL(browser(), url2_);
1342 // old_web_contents goes out of scope.
1345 // Check that the sessionStorage data is going to be persisted.
1346 content::NavigationController* controller =
1347 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1348 EXPECT_TRUE(
1349 controller->GetDefaultSessionStorageNamespace()->should_persist());
1351 // Quit and restore. Check that no extra tabs were created.
1352 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1353 ASSERT_EQ(1u, active_browser_list_->size());
1354 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
1357 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreSimpleTest, CorrectLoadingOrder) {
1358 ASSERT_EQ(SessionRestore::SMART_RESTORE_MODE_SIMPLE,
1359 SessionRestore::GetSmartRestoreMode());
1361 const int num_tabs = 6;
1363 // Start observing the loading of tabs, to make sure the order is correct.
1364 StartObserving(num_tabs);
1366 struct TabInfo {
1367 GURL url;
1368 bool pinned;
1369 int expected_load_order;
1372 TabInfo tab_info[num_tabs] = {
1373 // This will be the foreground tab and will always load first.
1374 {GURL("http://google.com/1"), false, 1},
1375 {GURL("http://google.com/2"), false, 3},
1376 // Internal page, should load last.
1377 {GURL(chrome::kChromeUINewTabURL), false, 6},
1378 {GURL("http://google.com/4"), false, 4},
1379 {GURL("http://google.com/5"), true, 2}, // Pinned, should load second.
1380 {GURL("http://google.com/6"), false, 5},
1383 // Set up the restore data.
1384 std::vector<const sessions::SessionWindow*> session;
1385 sessions::SessionWindow window;
1386 sessions::SessionTab tab[num_tabs];
1388 for (int i = 0; i < num_tabs; i++) {
1389 SerializedNavigationEntry nav =
1390 SerializedNavigationEntryTestHelper::CreateNavigation(
1391 tab_info[i].url.spec(), tab_info[i].url.spec().c_str());
1392 sync_pb::SessionTab sync_data;
1393 sync_data.set_tab_visual_index(0);
1394 sync_data.set_current_navigation_index(0);
1395 sync_data.add_navigation()->CopyFrom(nav.ToSyncData());
1396 sync_data.set_pinned(tab_info[i].pinned);
1397 tab[i].SetFromSyncData(sync_data, base::Time::Now());
1398 window.tabs.push_back(tab + i);
1401 session.push_back(&window);
1402 Profile* profile = browser()->profile();
1403 std::vector<Browser*> browsers = SessionRestore::RestoreForeignSessionWindows(
1404 profile, browser()->host_desktop_type(), session.begin(), session.end());
1406 ASSERT_EQ(1u, browsers.size());
1407 ASSERT_TRUE(browsers[0]);
1408 ASSERT_EQ(num_tabs, browsers[0]->tab_strip_model()->count());
1410 WaitForAllTabsToStartLoading();
1412 ASSERT_EQ(static_cast<size_t>(num_tabs), web_contents().size());
1414 // Make sure that contents are loaded in the correct order, ie. each tab rank
1415 // is higher that its preceding one.
1416 std::map<GURL, int> ranks;
1417 for (auto t : tab_info)
1418 ranks[t.url] = t.expected_load_order;
1419 for (size_t i = 1; i < web_contents().size(); i++) {
1420 int current_rank = ranks[web_contents()[i]->GetLastCommittedURL()];
1421 int previous_rank = ranks[web_contents()[i - 1]->GetLastCommittedURL()];
1422 ASSERT_LT(previous_rank, current_rank);
1425 // The SessionWindow destructor deletes the tabs, so we have to clear them
1426 // here to avoid a crash.
1427 window.tabs.clear();
1430 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreMRUTest, CorrectLoadingOrder) {
1431 const int num_tabs = 6;
1433 Profile* profile = browser()->profile();
1435 GURL urls[] = {GURL("http://google.com/1"),
1436 GURL("http://google.com/2"),
1437 GURL("http://google.com/3"),
1438 GURL("http://google.com/4"),
1439 GURL("http://google.com/5"),
1440 GURL("http://google.com/6")};
1442 int activation_order[] = {4, 2, 1, 5, 0, 3};
1443 int activation_order2[] = {4, 2, 5, 0, 3, 1};
1445 // Replace the first tab and add the other tabs.
1446 ui_test_utils::NavigateToURL(browser(), urls[0]);
1447 for (int i = 1; i < num_tabs; i++) {
1448 ui_test_utils::NavigateToURLWithDisposition(
1449 browser(), urls[i], NEW_FOREGROUND_TAB,
1450 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1453 ASSERT_EQ(num_tabs, browser()->tab_strip_model()->count());
1455 // Activate the tabs one by one following the random activation order.
1456 for (auto i : activation_order)
1457 browser()->tab_strip_model()->ActivateTabAt(i, true);
1459 // Close the browser.
1460 g_browser_process->AddRefModule();
1461 CloseBrowserSynchronously(browser());
1463 StartObserving(num_tabs);
1465 // Create a new window, which should trigger session restore.
1466 ui_test_utils::BrowserAddedObserver window_observer;
1467 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
1468 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
1469 ASSERT_TRUE(new_browser != NULL);
1470 WaitForAllTabsToStartLoading();
1471 g_browser_process->ReleaseModule();
1473 ASSERT_EQ(static_cast<size_t>(num_tabs), web_contents().size());
1474 // Test that we have observed the tabs being loaded in the inverse order of
1475 // their activation (MRU). Also validate that their last active time is in the
1476 // correct order.
1477 for (size_t i = 0; i < web_contents().size(); i++) {
1478 GURL expected_url = urls[activation_order[num_tabs - i - 1]];
1479 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL());
1480 if (i > 0) {
1481 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(),
1482 web_contents()[i]->GetLastActiveTime());
1486 // Activate the 2nd tab then close the browser and open it again, to trigger
1487 // another session restore. The goal is to ensure that activation time is
1488 // persisted between session restores.
1490 new_browser->tab_strip_model()->ActivateTabAt(1, true);
1492 // Close the browser.
1493 g_browser_process->AddRefModule();
1494 CloseBrowserSynchronously(new_browser);
1496 StartObserving(num_tabs);
1498 // Create a new window, which should trigger session restore.
1499 ui_test_utils::BrowserAddedObserver window_observer2;
1500 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
1501 Browser* new_browser2 = window_observer2.WaitForSingleNewBrowser();
1502 ASSERT_TRUE(new_browser2 != NULL);
1503 WaitForAllTabsToStartLoading();
1504 g_browser_process->ReleaseModule();
1506 ASSERT_EQ(static_cast<size_t>(num_tabs), web_contents().size());
1508 // Test that we have observed the tabs being loaded in the inverse order of
1509 // their activation (MRU). Also validate that their last active time is in the
1510 // correct order.
1511 for (size_t i = 0; i < web_contents().size(); i++) {
1512 GURL expected_url = urls[activation_order2[num_tabs - i - 1]];
1513 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL());
1514 if (i > 0) {
1515 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(),
1516 web_contents()[i]->GetLastActiveTime());