BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / sessions / session_restore_browsertest.cc
blobb5b702b5ef0406726aaa492d5f42f925adeacc73
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_factory.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/browser/ui/browser_tabstrip.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/host_desktop.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/url_constants.h"
33 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/test_switches.h"
35 #include "chrome/test/base/ui_test_utils.h"
36 #include "components/sessions/content/content_live_tab.h"
37 #include "components/sessions/core/tab_restore_service.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 Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) {
113 return QuitBrowserAndRestoreWithURL(
114 browser, expected_tab_count, GURL(), true);
117 Browser* QuitBrowserAndRestoreWithURL(Browser* browser,
118 int expected_tab_count,
119 const GURL& url,
120 bool no_memory_pressure) {
121 Profile* profile = browser->profile();
123 // Close the browser.
124 g_browser_process->AddRefModule();
125 CloseBrowserSynchronously(browser);
127 // Create a new window, which should trigger session restore.
128 ui_test_utils::BrowserAddedObserver window_observer;
129 SessionRestoreTestHelper restore_observer;
130 if (url.is_empty()) {
131 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
132 } else {
133 chrome::NavigateParams params(profile,
134 url,
135 ui::PAGE_TRANSITION_LINK);
136 chrome::Navigate(&params);
138 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
139 // Stop loading anything more if we are running out of space.
140 if (!no_memory_pressure) {
141 base::MemoryPressureListener::NotifyMemoryPressure(
142 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
144 restore_observer.Wait();
146 if (no_memory_pressure)
147 WaitForTabsToLoad(new_browser);
149 g_browser_process->ReleaseModule();
151 return new_browser;
154 void GoBack(Browser* browser) {
155 content::TestNavigationObserver observer(
156 browser->tab_strip_model()->GetActiveWebContents());
157 chrome::GoBack(browser, CURRENT_TAB);
158 observer.Wait();
161 void GoForward(Browser* browser) {
162 content::TestNavigationObserver observer(
163 browser->tab_strip_model()->GetActiveWebContents());
164 chrome::GoForward(browser, CURRENT_TAB);
165 observer.Wait();
168 void AssertOneWindowWithOneTab(Browser* browser) {
169 ASSERT_EQ(1u, active_browser_list_->size());
170 ASSERT_EQ(1, browser->tab_strip_model()->count());
173 int RenderProcessHostCount() {
174 content::RenderProcessHost::iterator hosts =
175 content::RenderProcessHost::AllHostsIterator();
176 int count = 0;
177 while (!hosts.IsAtEnd()) {
178 if (hosts.GetCurrentValue()->HasConnection())
179 count++;
180 hosts.Advance();
182 return count;
185 void WaitForTabsToLoad(Browser* browser) {
186 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
187 content::WebContents* contents =
188 browser->tab_strip_model()->GetWebContentsAt(i);
189 contents->GetController().LoadIfNecessary();
190 content::WaitForLoadStop(contents);
194 GURL url1_;
195 GURL url2_;
196 GURL url3_;
198 const BrowserList* active_browser_list_;
201 // Activates the smart restore behaviour in "simple" mode and tracks the loading
202 // of tabs.
203 class SmartSessionRestoreSimpleTest : public SessionRestoreTest,
204 public content::NotificationObserver {
205 public:
206 SmartSessionRestoreSimpleTest() {}
207 void StartObserving(int num_tabs) {
208 // Start by clearing everything so it can be reused in the same test.
209 web_contents_.clear();
210 registrar_.RemoveAll();
211 num_tabs_ = num_tabs;
212 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
213 content::NotificationService::AllSources());
215 void Observe(int type,
216 const content::NotificationSource& source,
217 const content::NotificationDetails& details) override {
218 switch (type) {
219 case content::NOTIFICATION_LOAD_START: {
220 content::NavigationController* controller =
221 content::Source<content::NavigationController>(source).ptr();
222 web_contents_.push_back(controller->GetWebContents());
223 if (web_contents_.size() == static_cast<size_t>(num_tabs_))
224 message_loop_runner_->Quit();
225 break;
229 const std::vector<content::WebContents*>& web_contents() const {
230 return web_contents_;
233 void WaitForAllTabsToStartLoading() {
234 message_loop_runner_ = new content::MessageLoopRunner;
235 message_loop_runner_->Run();
238 protected:
239 static const int kExpectedNumTabs;
240 static const char* const kUrls[];
241 void SetUpCommandLine(base::CommandLine* command_line) override {
242 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
243 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/");
244 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
245 switches::kForceFieldTrialParams,
246 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/simple");
249 private:
250 content::NotificationRegistrar registrar_;
251 // Ordered by load start order.
252 std::vector<content::WebContents*> web_contents_;
253 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
254 int num_tabs_;
256 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreSimpleTest);
259 class SmartSessionRestoreMRUTest : public SmartSessionRestoreSimpleTest {
260 public:
261 SmartSessionRestoreMRUTest() {}
263 protected:
264 void SetUpCommandLine(base::CommandLine* command_line) override {
265 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
266 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/");
267 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
268 switches::kForceFieldTrialParams,
269 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/mru");
272 private:
273 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreMRUTest);
276 // static
277 const int SmartSessionRestoreSimpleTest::kExpectedNumTabs = 6;
278 // static
279 const char* const SmartSessionRestoreSimpleTest::kUrls[] = {
280 "http://google.com/1",
281 "http://google.com/2",
282 "http://google.com/3",
283 "http://google.com/4",
284 "http://google.com/5",
285 "http://google.com/6"};
287 // Verifies that restored tabs have a root window. This is important
288 // otherwise the wrong information is communicated to the renderer.
289 // (http://crbug.com/342672).
290 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveWindow) {
291 // Create tabs.
292 ui_test_utils::NavigateToURLWithDisposition(
293 browser(),
294 GURL(url::kAboutBlankURL),
295 NEW_FOREGROUND_TAB,
296 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
297 ui_test_utils::NavigateToURLWithDisposition(
298 browser(),
299 GURL(url::kAboutBlankURL),
300 NEW_BACKGROUND_TAB,
301 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
303 // Restart and session restore the tabs.
304 Browser* restored = QuitBrowserAndRestore(browser(), 3);
305 TabStripModel* tab_strip_model = restored->tab_strip_model();
306 const int tabs = tab_strip_model->count();
307 ASSERT_EQ(3, tabs);
309 // Check the restored tabs have a window to get screen info from.
310 // On Aura it should also have a root window.
311 for (int i = 0; i < tabs; ++i) {
312 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
313 EXPECT_TRUE(contents->GetTopLevelNativeWindow());
314 #if defined(USE_AURA)
315 EXPECT_TRUE(contents->GetNativeView()->GetRootWindow());
316 #endif
320 // Verify that restored tabs have correct disposition. Only one tab should
321 // have "visible" visibility state, the rest should not.
322 // (http://crbug.com/155365 http://crbug.com/118269)
323 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
324 RestoredTabsHaveCorrectVisibilityState) {
325 // Create tabs.
326 GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(),
327 base::FilePath(FILE_PATH_LITERAL("tab-restore-visibility.html"))));
328 ui_test_utils::NavigateToURLWithDisposition(
329 browser(), test_page, NEW_FOREGROUND_TAB,
330 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
331 ui_test_utils::NavigateToURLWithDisposition(
332 browser(), test_page, NEW_BACKGROUND_TAB,
333 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
335 // Restart and session restore the tabs.
336 content::DOMMessageQueue message_queue;
337 Browser* restored = QuitBrowserAndRestore(browser(), 3);
338 for (int i = 0; i < 2; ++i) {
339 std::string message;
340 EXPECT_TRUE(message_queue.WaitForMessage(&message));
341 EXPECT_EQ("\"READY\"", message);
344 // There should be 3 restored tabs in the new browser.
345 TabStripModel* tab_strip_model = restored->tab_strip_model();
346 const int tabs = tab_strip_model->count();
347 ASSERT_EQ(3, tabs);
349 // The middle tab only should have visible disposition.
350 for (int i = 0; i < tabs; ++i) {
351 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
352 std::string document_visibility_state;
353 const char kGetStateJS[] = "window.domAutomationController.send("
354 "window.document.visibilityState);";
355 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
356 contents, kGetStateJS, &document_visibility_state));
357 if (i == 1) {
358 EXPECT_EQ("visible", document_visibility_state);
359 } else {
360 EXPECT_EQ("hidden", document_visibility_state);
365 #if defined(OS_CHROMEOS)
366 // Verify that session restore does not occur when a user opens a browser window
367 // when no other browser windows are open on ChromeOS.
368 // TODO(pkotwicz): Add test which doesn't open incognito browser once
369 // disable-zero-browsers-open-for-tests is removed.
370 // (http://crbug.com/119175)
371 // TODO(pkotwicz): Mac should have the behavior outlined by this test. It should
372 // not do session restore if an incognito window is already open.
373 // (http://crbug.com/120927)
374 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) {
375 GURL url(ui_test_utils::GetTestUrl(
376 base::FilePath(base::FilePath::kCurrentDirectory),
377 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
379 // Add a single tab.
380 ui_test_utils::NavigateToURL(browser(), url);
382 Browser* incognito_browser = CreateIncognitoBrowser();
383 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
384 incognito_browser->window()->Show();
386 // Close the normal browser. After this we only have the incognito window
387 // open.
388 CloseBrowserSynchronously(browser());
390 // Create a new window, which should open NTP.
391 ui_test_utils::BrowserAddedObserver browser_added_observer;
392 chrome::NewWindow(incognito_browser);
393 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
395 ASSERT_TRUE(new_browser);
396 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
397 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
398 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
401 // Test that maximized applications get restored maximized.
402 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MaximizedApps) {
403 const char* app_name = "TestApp";
404 Browser* app_browser = CreateBrowserForApp(app_name, browser()->profile());
405 app_browser->window()->Maximize();
406 app_browser->window()->Show();
407 EXPECT_TRUE(app_browser->window()->IsMaximized());
408 EXPECT_TRUE(app_browser->is_app());
409 EXPECT_TRUE(app_browser->is_type_popup());
411 // Close the normal browser. After this we only have the app_browser window.
412 CloseBrowserSynchronously(browser());
414 // Create a new window, which should open NTP.
415 ui_test_utils::BrowserAddedObserver browser_added_observer;
416 chrome::NewWindow(app_browser);
417 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
419 ASSERT_TRUE(new_browser);
420 EXPECT_TRUE(app_browser->window()->IsMaximized());
421 EXPECT_TRUE(app_browser->is_app());
422 EXPECT_TRUE(app_browser->is_type_popup());
424 #endif // OS_CHROMEOS
426 #if !defined(OS_CHROMEOS)
427 // This test does not apply to ChromeOS as it does not do session restore when
428 // a new window is opened.
430 #if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
431 // Crashes on Linux Views: http://crbug.com/39476
432 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
433 DISABLED_RestoreOnNewWindowWithNoTabbedBrowsers
434 #else
435 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
436 RestoreOnNewWindowWithNoTabbedBrowsers
437 #endif
439 // Makes sure when session restore is triggered in the same process we don't end
440 // up with an extra tab.
441 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
442 MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers) {
443 const base::FilePath::CharType* kTitle1File =
444 FILE_PATH_LITERAL("title1.html");
445 GURL url(ui_test_utils::GetTestUrl(base::FilePath(
446 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
447 ui_test_utils::NavigateToURL(browser(), url);
449 // Turn on session restore.
450 SessionStartupPref::SetStartupPref(
451 browser()->profile(),
452 SessionStartupPref(SessionStartupPref::LAST));
454 // Create a new popup.
455 Profile* profile = browser()->profile();
456 Browser* popup =
457 new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile,
458 browser()->host_desktop_type()));
459 popup->window()->Show();
461 // Close the browser.
462 CloseBrowserSynchronously(browser());
464 // Create a new window, which should trigger session restore.
465 ui_test_utils::BrowserAddedObserver observer;
466 chrome::NewWindow(popup);
467 Browser* new_browser = observer.WaitForSingleNewBrowser();
469 ASSERT_TRUE(new_browser != NULL);
471 // The browser should only have one tab.
472 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
474 // And the first url should be url.
475 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
477 #endif // !OS_CHROMEOS
479 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreIndividualTabFromWindow) {
480 GURL url1(ui_test_utils::GetTestUrl(
481 base::FilePath(base::FilePath::kCurrentDirectory),
482 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
483 // Any page that will yield a 200 status code will work here.
484 GURL url2("chrome://version");
485 GURL url3(ui_test_utils::GetTestUrl(
486 base::FilePath(base::FilePath::kCurrentDirectory),
487 base::FilePath(FILE_PATH_LITERAL("title3.html"))));
489 // Add and navigate three tabs.
490 ui_test_utils::NavigateToURL(browser(), url1);
492 content::WindowedNotificationObserver observer(
493 content::NOTIFICATION_LOAD_STOP,
494 content::NotificationService::AllSources());
495 chrome::AddSelectedTabWithURL(browser(), url2,
496 ui::PAGE_TRANSITION_LINK);
497 observer.Wait();
500 content::WindowedNotificationObserver observer(
501 content::NOTIFICATION_LOAD_STOP,
502 content::NotificationService::AllSources());
503 chrome::AddSelectedTabWithURL(browser(), url3,
504 ui::PAGE_TRANSITION_LINK);
505 observer.Wait();
508 sessions::TabRestoreService* service =
509 TabRestoreServiceFactory::GetForProfile(browser()->profile());
510 service->ClearEntries();
512 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
514 browser()->window()->Close();
516 // Expect a window with three tabs.
517 ASSERT_EQ(1U, service->entries().size());
518 ASSERT_EQ(sessions::TabRestoreService::WINDOW,
519 service->entries().front()->type);
520 const sessions::TabRestoreService::Window* window =
521 static_cast<sessions::TabRestoreService::Window*>(
522 service->entries().front());
523 EXPECT_EQ(3U, window->tabs.size());
525 // Find the SessionID for entry2. Since the session service was destroyed,
526 // there is no guarantee that the SessionID for the tab has remained the same.
527 base::Time timestamp;
528 int http_status_code = 0;
529 for (std::vector<sessions::TabRestoreService::Tab>::const_iterator it =
530 window->tabs.begin();
531 it != window->tabs.end(); ++it) {
532 const sessions::TabRestoreService::Tab& tab = *it;
533 // If this tab held url2, then restore this single tab.
534 if (tab.navigations[0].virtual_url() == url2) {
535 timestamp = tab.navigations[0].timestamp();
536 http_status_code = tab.navigations[0].http_status_code();
537 std::vector<sessions::LiveTab*> content =
538 service->RestoreEntryById(NULL, tab.id, host_desktop_type, UNKNOWN);
539 ASSERT_EQ(1U, content.size());
540 ASSERT_TRUE(content[0]);
541 EXPECT_EQ(url2, static_cast<sessions::ContentLiveTab*>(content[0])
542 ->web_contents()
543 ->GetURL());
544 break;
547 EXPECT_FALSE(timestamp.is_null());
548 EXPECT_EQ(200, http_status_code);
550 // Make sure that the restored tab is removed from the service.
551 ASSERT_EQ(1U, service->entries().size());
552 ASSERT_EQ(sessions::TabRestoreService::WINDOW,
553 service->entries().front()->type);
554 window = static_cast<sessions::TabRestoreService::Window*>(
555 service->entries().front());
556 EXPECT_EQ(2U, window->tabs.size());
558 // Make sure that the restored tab was restored with the correct
559 // timestamp and status code.
560 const content::WebContents* contents =
561 browser()->tab_strip_model()->GetActiveWebContents();
562 ASSERT_TRUE(contents);
563 const content::NavigationEntry* entry =
564 contents->GetController().GetActiveEntry();
565 ASSERT_TRUE(entry);
566 EXPECT_EQ(timestamp, entry->GetTimestamp());
567 EXPECT_EQ(http_status_code, entry->GetHttpStatusCode());
570 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) {
571 GURL url(ui_test_utils::GetTestUrl(
572 base::FilePath(base::FilePath::kCurrentDirectory),
573 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
575 // Add a single tab.
576 ui_test_utils::NavigateToURL(browser(), url);
578 sessions::TabRestoreService* service =
579 TabRestoreServiceFactory::GetForProfile(browser()->profile());
580 service->ClearEntries();
581 EXPECT_EQ(0U, service->entries().size());
583 chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
585 // Close the window.
586 browser()->window()->Close();
588 // Expect the window to be converted to a tab by the TRS.
589 EXPECT_EQ(1U, service->entries().size());
590 ASSERT_EQ(sessions::TabRestoreService::TAB, service->entries().front()->type);
591 const sessions::TabRestoreService::Tab* tab =
592 static_cast<sessions::TabRestoreService::Tab*>(
593 service->entries().front());
595 // Restore the tab.
596 std::vector<sessions::LiveTab*> content =
597 service->RestoreEntryById(NULL, tab->id, host_desktop_type, UNKNOWN);
598 ASSERT_EQ(1U, content.size());
599 ASSERT_TRUE(content[0]);
600 EXPECT_EQ(url, static_cast<sessions::ContentLiveTab*>(content[0])
601 ->web_contents()
602 ->GetURL());
604 // Make sure the restore was successful.
605 EXPECT_EQ(0U, service->entries().size());
608 #if !defined(OS_CHROMEOS)
609 // This test does not apply to ChromeOS as ChromeOS does not do session
610 // restore when a new window is open.
612 // Verifies we remember the last browser window when closing the last
613 // non-incognito window while an incognito window is open.
614 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) {
615 GURL url(ui_test_utils::GetTestUrl(
616 base::FilePath(base::FilePath::kCurrentDirectory),
617 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
619 // Add a single tab.
620 ui_test_utils::NavigateToURL(browser(), url);
622 // Create a new incognito window.
623 Browser* incognito_browser = CreateIncognitoBrowser();
624 chrome::AddTabAt(incognito_browser, GURL(), -1, true);
625 incognito_browser->window()->Show();
627 // Close the normal browser. After this we only have the incognito window
628 // open.
629 CloseBrowserSynchronously(browser());
631 // Create a new window, which should trigger session restore.
632 ui_test_utils::BrowserAddedObserver browser_added_observer;
633 chrome::NewWindow(incognito_browser);
634 Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
636 // The first tab should have 'url' as its url.
637 ASSERT_TRUE(new_browser);
638 EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
640 #endif // !OS_CHROMEOS
642 namespace {
644 // Verifies that the given NavigationController has exactly two
645 // entries that correspond to the given URLs and that all but the last
646 // entry have null timestamps.
647 void VerifyNavigationEntries(
648 const content::NavigationController& controller,
649 GURL url1, GURL url2) {
650 ASSERT_EQ(2, controller.GetEntryCount());
651 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
652 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
653 EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL());
654 EXPECT_TRUE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
655 EXPECT_FALSE(controller.GetEntryAtIndex(1)->GetTimestamp().is_null());
658 } // namespace
660 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) {
661 GURL url1("http://google.com");
662 GURL url2("http://google2.com");
663 SerializedNavigationEntry nav1 =
664 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
665 SerializedNavigationEntry nav2 =
666 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
668 // Set up the restore data.
669 sync_pb::SessionTab sync_data;
670 sync_data.set_tab_visual_index(0);
671 sync_data.set_current_navigation_index(1);
672 sync_data.set_pinned(false);
673 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
674 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
676 sessions::SessionTab tab;
677 tab.SetFromSyncData(sync_data, base::Time::Now());
678 EXPECT_EQ(2U, tab.navigations.size());
679 for (size_t i = 0; i < tab.navigations.size(); ++i)
680 EXPECT_TRUE(tab.navigations[i].timestamp().is_null());
682 ASSERT_EQ(1, browser()->tab_strip_model()->count());
684 // Restore in the current tab.
685 content::WebContents* tab_content = NULL;
687 content::WindowedNotificationObserver observer(
688 content::NOTIFICATION_LOAD_STOP,
689 content::NotificationService::AllSources());
690 tab_content = SessionRestore::RestoreForeignSessionTab(
691 browser()->tab_strip_model()->GetActiveWebContents(), tab, CURRENT_TAB);
692 observer.Wait();
694 ASSERT_EQ(1, browser()->tab_strip_model()->count());
695 content::WebContents* web_contents =
696 browser()->tab_strip_model()->GetWebContentsAt(0);
697 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
698 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
699 ASSERT_TRUE(tab_content);
700 ASSERT_EQ(url2, tab_content->GetURL());
702 // Restore in a new tab.
703 tab_content = NULL;
705 content::WindowedNotificationObserver observer(
706 content::NOTIFICATION_LOAD_STOP,
707 content::NotificationService::AllSources());
708 tab_content = SessionRestore::RestoreForeignSessionTab(
709 browser()->tab_strip_model()->GetActiveWebContents(),
710 tab, NEW_BACKGROUND_TAB);
711 observer.Wait();
713 ASSERT_EQ(2, browser()->tab_strip_model()->count());
714 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
715 web_contents = browser()->tab_strip_model()->GetWebContentsAt(1);
716 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
717 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
718 ASSERT_TRUE(tab_content);
719 ASSERT_EQ(url2, tab_content->GetURL());
721 // Restore in a new window.
722 Browser* new_browser = NULL;
723 tab_content = NULL;
725 ui_test_utils::BrowserAddedObserver browser_observer;
726 content::WindowedNotificationObserver observer(
727 content::NOTIFICATION_LOAD_STOP,
728 content::NotificationService::AllSources());
729 tab_content = SessionRestore::RestoreForeignSessionTab(
730 browser()->tab_strip_model()->GetActiveWebContents(), tab, NEW_WINDOW);
731 new_browser = browser_observer.WaitForSingleNewBrowser();
732 observer.Wait();
735 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
736 web_contents = new_browser->tab_strip_model()->GetWebContentsAt(0);
737 VerifyNavigationEntries(web_contents->GetController(), url1, url2);
738 ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
739 ASSERT_TRUE(tab_content);
740 ASSERT_EQ(url2, tab_content->GetURL());
743 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) {
744 Profile* profile = browser()->profile();
746 GURL url1("http://google.com");
747 GURL url2("http://google2.com");
748 SerializedNavigationEntry nav1 =
749 SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
750 SerializedNavigationEntry nav2 =
751 SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
752 SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav2);
754 // Set up the restore data -- one window with two tabs.
755 std::vector<const sessions::SessionWindow*> session;
756 sessions::SessionWindow window;
757 sessions::SessionTab tab1;
759 sync_pb::SessionTab sync_data;
760 sync_data.set_tab_visual_index(0);
761 sync_data.set_current_navigation_index(0);
762 sync_data.set_pinned(true);
763 sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
764 tab1.SetFromSyncData(sync_data, base::Time::Now());
766 window.tabs.push_back(&tab1);
768 sessions::SessionTab tab2;
770 sync_pb::SessionTab sync_data;
771 sync_data.set_tab_visual_index(1);
772 sync_data.set_current_navigation_index(0);
773 sync_data.set_pinned(false);
774 sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
775 tab2.SetFromSyncData(sync_data, base::Time::Now());
777 window.tabs.push_back(&tab2);
779 // Leave tab3 empty. Should have no effect on restored session, but simulates
780 // partially complete foreign session data.
781 sessions::SessionTab tab3;
782 window.tabs.push_back(&tab3);
784 session.push_back(static_cast<const sessions::SessionWindow*>(&window));
785 ui_test_utils::BrowserAddedObserver window_observer;
786 std::vector<Browser*> browsers =
787 SessionRestore::RestoreForeignSessionWindows(
788 profile, browser()->host_desktop_type(), session.begin(),
789 session.end());
790 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
791 ASSERT_TRUE(new_browser);
792 ASSERT_EQ(2u, active_browser_list_->size());
793 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
795 ASSERT_EQ(1u, browsers.size());
796 ASSERT_TRUE(browsers[0]);
797 ASSERT_EQ(2, browsers[0]->tab_strip_model()->count());
799 content::WebContents* web_contents_1 =
800 new_browser->tab_strip_model()->GetWebContentsAt(0);
801 content::WebContents* web_contents_2 =
802 new_browser->tab_strip_model()->GetWebContentsAt(1);
803 ASSERT_EQ(url1, web_contents_1->GetURL());
804 ASSERT_EQ(url2, web_contents_2->GetURL());
806 // Check user agent override state.
807 ASSERT_TRUE(web_contents_1->GetUserAgentOverride().empty());
808 ASSERT_TRUE(web_contents_2->GetUserAgentOverride().empty());
810 content::NavigationEntry* entry =
811 web_contents_1->GetController().GetActiveEntry();
812 ASSERT_TRUE(entry);
813 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
815 entry = web_contents_2->GetController().GetActiveEntry();
816 ASSERT_TRUE(entry);
817 ASSERT_FALSE(entry->GetIsOverridingUserAgent());
819 // The SessionWindow destructor deletes the tabs, so we have to clear them
820 // here to avoid a crash.
821 window.tabs.clear();
824 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) {
825 ui_test_utils::NavigateToURL(browser(), url1_);
826 ui_test_utils::NavigateToURL(browser(), url2_);
828 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
829 ASSERT_EQ(1u, active_browser_list_->size());
830 ASSERT_EQ(url2_,
831 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
832 GoBack(new_browser);
833 ASSERT_EQ(url1_,
834 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
837 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoMemoryPressureLoadsAllTabs) {
838 // Add several tabs to the browser. Restart the browser and check that all
839 // tabs got loaded properly.
840 ui_test_utils::NavigateToURLWithDisposition(
841 browser(),
842 GURL(url::kAboutBlankURL),
843 NEW_FOREGROUND_TAB,
844 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
845 ui_test_utils::NavigateToURLWithDisposition(
846 browser(),
847 GURL(url::kAboutBlankURL),
848 NEW_FOREGROUND_TAB,
849 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
850 Browser* restored =
851 QuitBrowserAndRestoreWithURL(browser(), 1, GURL(), true);
852 TabStripModel* tab_strip_model = restored->tab_strip_model();
854 ASSERT_EQ(1u, active_browser_list_->size());
856 ASSERT_EQ(3, tab_strip_model->count());
857 // All render widgets should be initialized by now.
858 ASSERT_TRUE(
859 tab_strip_model->GetWebContentsAt(0)->GetRenderWidgetHostView() &&
860 tab_strip_model->GetWebContentsAt(1)->GetRenderWidgetHostView() &&
861 tab_strip_model->GetWebContentsAt(2)->GetRenderWidgetHostView());
864 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MemoryPressureLoadsNotAllTabs) {
865 // Add several tabs to the browser. Restart the browser and check that all
866 // tabs got loaded properly.
867 ui_test_utils::NavigateToURLWithDisposition(
868 browser(),
869 GURL(url::kAboutBlankURL),
870 NEW_FOREGROUND_TAB,
871 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
872 ui_test_utils::NavigateToURLWithDisposition(
873 browser(),
874 GURL(url::kAboutBlankURL),
875 NEW_FOREGROUND_TAB,
876 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
877 // Restore the brwoser, but instead of directly waiting, we issue a critical
878 // memory pressure event and finish then the loading.
879 Browser* restored =
880 QuitBrowserAndRestoreWithURL(browser(), 1, GURL(), false);
882 TabStripModel* tab_strip_model = restored->tab_strip_model();
884 ASSERT_EQ(1u, active_browser_list_->size());
886 ASSERT_EQ(3, tab_strip_model->count());
887 // At least one of the render widgets should not be initialized yet.
888 ASSERT_FALSE(
889 tab_strip_model->GetWebContentsAt(0)->GetRenderWidgetHostView() &&
890 tab_strip_model->GetWebContentsAt(1)->GetRenderWidgetHostView() &&
891 tab_strip_model->GetWebContentsAt(2)->GetRenderWidgetHostView());
894 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) {
895 const GURL webui_url("chrome://omnibox");
896 ui_test_utils::NavigateToURL(browser(), webui_url);
897 const content::WebContents* old_tab =
898 browser()->tab_strip_model()->GetActiveWebContents();
899 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
900 old_tab->GetRenderViewHost()->GetEnabledBindings());
902 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
903 ASSERT_EQ(1u, active_browser_list_->size());
904 const content::WebContents* new_tab =
905 new_browser->tab_strip_model()->GetActiveWebContents();
906 EXPECT_EQ(webui_url, new_tab->GetURL());
907 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
908 new_tab->GetRenderViewHost()->GetEnabledBindings());
911 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUISettings) {
912 const GURL webui_url("chrome://settings");
913 ui_test_utils::NavigateToURL(browser(), webui_url);
914 const content::WebContents* old_tab =
915 browser()->tab_strip_model()->GetActiveWebContents();
916 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
917 old_tab->GetRenderViewHost()->GetEnabledBindings());
919 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
920 ASSERT_EQ(1u, active_browser_list_->size());
921 const content::WebContents* new_tab =
922 new_browser->tab_strip_model()->GetActiveWebContents();
923 EXPECT_EQ(webui_url, new_tab->GetURL());
924 EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
925 new_tab->GetRenderViewHost()->GetEnabledBindings());
928 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) {
929 ui_test_utils::NavigateToURL(browser(), url1_);
930 ui_test_utils::NavigateToURL(browser(), url2_);
931 ui_test_utils::NavigateToURL(browser(), url3_);
933 GoBack(browser());
934 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
935 ASSERT_EQ(1u, active_browser_list_->size());
936 ASSERT_EQ(url2_,
937 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
938 GoForward(new_browser);
939 ASSERT_EQ(url3_,
940 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
941 GoBack(new_browser);
942 ASSERT_EQ(url2_,
943 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
945 // Test renderer-initiated back/forward as well.
946 GURL go_back_url("javascript:history.back();");
947 ui_test_utils::NavigateToURL(new_browser, go_back_url);
948 ASSERT_EQ(url1_,
949 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
952 // Tests that the SiteInstances used for entries in a restored tab's history
953 // are given appropriate max page IDs, so that going back to a restored
954 // cross-site page and then forward again works. (Bug 1204135)
955 // This test fails. See http://crbug.com/237497.
956 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
957 DISABLED_RestoresCrossSiteForwardAndBackwardNavs) {
958 ASSERT_TRUE(test_server()->Start());
960 GURL cross_site_url(test_server()->GetURL("files/title2.html"));
962 // Visit URLs on different sites.
963 ui_test_utils::NavigateToURL(browser(), url1_);
964 ui_test_utils::NavigateToURL(browser(), cross_site_url);
965 ui_test_utils::NavigateToURL(browser(), url2_);
967 GoBack(browser());
968 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
969 ASSERT_EQ(1u, active_browser_list_->size());
970 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
972 // Check that back and forward work as expected.
973 ASSERT_EQ(cross_site_url,
974 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
976 GoBack(new_browser);
977 ASSERT_EQ(url1_,
978 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
980 GoForward(new_browser);
981 ASSERT_EQ(cross_site_url,
982 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
984 // Test renderer-initiated back/forward as well.
985 GURL go_forward_url("javascript:history.forward();");
986 ui_test_utils::NavigateToURL(new_browser, go_forward_url);
987 ASSERT_EQ(url2_,
988 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
991 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) {
992 ui_test_utils::NavigateToURL(browser(), url1_);
994 ui_test_utils::NavigateToURLWithDisposition(
995 browser(), url2_, NEW_FOREGROUND_TAB,
996 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
998 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
1000 ASSERT_EQ(1u, active_browser_list_->size());
1001 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1002 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1003 ASSERT_EQ(url2_,
1004 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1006 ASSERT_EQ(url1_,
1007 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
1010 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
1011 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) {
1012 ui_test_utils::NavigateToURL(browser(), url1_);
1014 ui_test_utils::NavigateToURLWithDisposition(
1015 browser(), url2_, NEW_FOREGROUND_TAB,
1016 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1017 chrome::CloseTab(browser());
1019 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1021 AssertOneWindowWithOneTab(new_browser);
1022 ASSERT_EQ(url1_,
1023 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1026 // Ensures active tab properly restored when tabs before it closed.
1027 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtClose) {
1028 ui_test_utils::NavigateToURL(browser(), url1_);
1029 ui_test_utils::NavigateToURLWithDisposition(
1030 browser(), url2_, NEW_FOREGROUND_TAB,
1031 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1032 ui_test_utils::NavigateToURLWithDisposition(
1033 browser(), url3_, NEW_BACKGROUND_TAB,
1034 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1036 browser()->tab_strip_model()->CloseWebContentsAt(
1038 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
1040 Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
1042 ASSERT_EQ(url2_,
1043 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1044 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 0);
1047 // Ensures active tab properly restored when tabs are inserted before it .
1048 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtInsert) {
1049 ui_test_utils::NavigateToURL(browser(), url1_);
1050 ui_test_utils::NavigateToURLWithDisposition(
1051 browser(), url2_, NEW_BACKGROUND_TAB,
1052 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1054 chrome::NavigateParams navigate_params(browser(), url3_,
1055 ui::PAGE_TRANSITION_TYPED);
1056 navigate_params.tabstrip_index = 0;
1057 navigate_params.disposition = NEW_BACKGROUND_TAB;
1058 ui_test_utils::NavigateToURL(&navigate_params);
1060 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
1062 ASSERT_EQ(url1_,
1063 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1064 ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1);
1067 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
1068 // This test doesn't apply to the Mac version; see GetCommandLineForRelaunch
1069 // for details. It was disabled for a long time so might never have worked on
1070 // ChromeOS.
1072 // Launches an app window, closes tabbed browser, launches and makes sure
1073 // we restore the tabbed browser url.
1074 // If this test flakes, use http://crbug.com/29110
1075 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
1076 RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
1077 #if defined(OS_WIN) && defined(USE_ASH)
1078 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1079 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1080 switches::kAshBrowserTests))
1081 return;
1082 #endif
1084 ui_test_utils::NavigateToURL(browser(), url1_);
1086 // Launch an app.
1087 base::CommandLine app_launch_arguments = GetCommandLineForRelaunch();
1088 app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
1090 ui_test_utils::BrowserAddedObserver window_observer;
1092 base::LaunchProcess(app_launch_arguments, base::LaunchOptionsForTest());
1094 Browser* app_window = window_observer.WaitForSingleNewBrowser();
1095 ASSERT_EQ(2u, active_browser_list_->size());
1097 // Close the first window. The only window left is the App window.
1098 CloseBrowserSynchronously(browser());
1100 // Restore the session, which should bring back the first window with url1_.
1101 Browser* new_browser = QuitBrowserAndRestore(app_window, 1);
1103 AssertOneWindowWithOneTab(new_browser);
1105 ASSERT_EQ(url1_,
1106 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1109 #endif // !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
1111 // Creates two windows, closes one, restores, make sure only one window open.
1112 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) {
1113 ui_test_utils::NavigateToURL(browser(), url1_);
1115 // Open a second window.
1116 ui_test_utils::NavigateToURLWithDisposition(
1117 browser(),
1118 GURL(url::kAboutBlankURL),
1119 NEW_WINDOW,
1120 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
1122 ASSERT_EQ(2u, active_browser_list_->size());
1124 // Close it.
1125 Browser* new_window = active_browser_list_->get(1);
1126 CloseBrowserSynchronously(new_window);
1128 // Restart and make sure we have only one window with one tab and the url
1129 // is url1_.
1130 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1132 AssertOneWindowWithOneTab(new_browser);
1134 ASSERT_EQ(url1_,
1135 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1138 // Make sure after a restore the number of processes matches that of the number
1139 // of processes running before the restore. This creates a new tab so that
1140 // we should have two new tabs running. (This test will pass in both
1141 // process-per-site and process-per-site-instance, because we treat the new tab
1142 // as a special case in process-per-site-instance so that it only ever uses one
1143 // process.)
1145 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
1146 // Unfortunately, the fix at http://codereview.chromium.org/6546078
1147 // breaks NTP background image refreshing, so ThemeSource had to revert to
1148 // replacing the existing data source.
1149 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) {
1150 // Create two new tabs.
1151 ui_test_utils::NavigateToURLWithDisposition(
1152 browser(),
1153 GURL(url::kAboutBlankURL),
1154 NEW_FOREGROUND_TAB,
1155 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1156 ui_test_utils::NavigateToURLWithDisposition(
1157 browser(),
1158 GURL(url::kAboutBlankURL),
1159 NEW_FOREGROUND_TAB,
1160 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1162 int expected_process_count = RenderProcessHostCount();
1164 // Restart.
1165 Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
1167 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1169 ASSERT_EQ(expected_process_count, RenderProcessHostCount());
1172 // Test that changing the user agent override will persist it to disk.
1173 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, PersistAndRestoreUserAgentOverride) {
1174 // Create a tab with an overridden user agent.
1175 ui_test_utils::NavigateToURL(browser(), url1_);
1176 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1177 browser()->tab_strip_model()->GetWebContentsAt(0)->
1178 SetUserAgentOverride("override");
1180 // Create a tab without an overridden user agent.
1181 ui_test_utils::NavigateToURLWithDisposition(
1182 browser(), url2_, NEW_FOREGROUND_TAB,
1183 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1184 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1186 // Kill the original browser then open a new one to trigger a restore.
1187 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1188 ASSERT_EQ(1u, active_browser_list_->size());
1189 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1190 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1192 // Confirm that the user agent overrides are properly set.
1193 EXPECT_EQ("override",
1194 new_browser->tab_strip_model()->GetWebContentsAt(0)->
1195 GetUserAgentOverride());
1196 EXPECT_EQ("",
1197 new_browser->tab_strip_model()->GetWebContentsAt(1)->
1198 GetUserAgentOverride());
1201 // Regression test for crbug.com/125958. When restoring a pinned selected tab in
1202 // a setting where there are existing tabs, the selected index computation was
1203 // wrong, leading to the wrong tab getting selected, DCHECKs firing, and the
1204 // pinned tab not getting loaded.
1205 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestorePinnedSelectedTab) {
1206 // Create a pinned tab.
1207 ui_test_utils::NavigateToURL(browser(), url1_);
1208 browser()->tab_strip_model()->SetTabPinned(0, true);
1209 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1210 // Create a nonpinned tab.
1211 ui_test_utils::NavigateToURLWithDisposition(
1212 browser(), url2_, NEW_FOREGROUND_TAB,
1213 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1214 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1215 // Select the pinned tab.
1216 browser()->tab_strip_model()->ActivateTabAt(0, true);
1217 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1218 Profile* profile = browser()->profile();
1220 // This will also initiate a session restore, but we're not interested in it.
1221 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1222 ASSERT_EQ(1u, active_browser_list_->size());
1223 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1224 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1225 // Close the pinned tab.
1226 chrome::CloseTab(new_browser);
1227 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1228 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1229 // Use the existing tab to navigate away, so that we can verify it was really
1230 // clobbered.
1231 ui_test_utils::NavigateToURL(new_browser, url3_);
1233 // Restore the session again, clobbering the existing tab.
1234 SessionRestore::RestoreSession(
1235 profile, new_browser,
1236 new_browser->host_desktop_type(),
1237 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1238 std::vector<GURL>());
1240 // The pinned tab is the selected tab.
1241 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1242 EXPECT_EQ(0, new_browser->tab_strip_model()->active_index());
1243 EXPECT_EQ(url1_,
1244 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1245 EXPECT_EQ(url2_,
1246 new_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL());
1249 // Regression test for crbug.com/240156. When restoring tabs with a navigation,
1250 // the navigation should take active tab focus.
1251 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWithNavigateSelectedTab) {
1252 // Create 2 tabs.
1253 ui_test_utils::NavigateToURL(browser(), url1_);
1254 ui_test_utils::NavigateToURLWithDisposition(
1255 browser(), url2_, NEW_FOREGROUND_TAB,
1256 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1258 // Restore the session by calling chrome::Navigate().
1259 Browser* new_browser =
1260 QuitBrowserAndRestoreWithURL(browser(), 3, url3_, true);
1261 ASSERT_EQ(1u, active_browser_list_->size());
1262 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1263 // Navigated url should be the active tab.
1264 ASSERT_EQ(url3_,
1265 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1268 // Do a clobber restore from the new tab page. This test follows the code path
1269 // of a crash followed by the user clicking restore from the new tab page.
1270 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClobberRestoreTest) {
1271 // Create 2 tabs.
1272 ui_test_utils::NavigateToURL(browser(), url1_);
1273 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
1274 ui_test_utils::NavigateToURLWithDisposition(
1275 browser(), url2_, NEW_FOREGROUND_TAB,
1276 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1277 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
1278 Profile* profile = browser()->profile();
1280 // This will also initiate a session restore, but we're not interested in it.
1281 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1282 ASSERT_EQ(1u, active_browser_list_->size());
1283 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1284 ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
1285 // Close the first tab.
1286 chrome::CloseTab(new_browser);
1287 ASSERT_EQ(1, new_browser->tab_strip_model()->count());
1288 ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
1289 // Use the existing tab to navigate to the NTP.
1290 ui_test_utils::NavigateToURL(new_browser, GURL(chrome::kChromeUINewTabURL));
1292 // Restore the session again, clobbering the existing tab.
1293 SessionRestore::RestoreSession(
1294 profile, new_browser,
1295 new_browser->host_desktop_type(),
1296 SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
1297 std::vector<GURL>());
1299 // 2 tabs should have been restored, with the existing tab clobbered, giving
1300 // us a total of 2 tabs.
1301 ASSERT_EQ(2, new_browser->tab_strip_model()->count());
1302 EXPECT_EQ(1, new_browser->tab_strip_model()->active_index());
1303 EXPECT_EQ(url1_,
1304 new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
1305 EXPECT_EQ(url2_,
1306 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1309 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) {
1310 ui_test_utils::NavigateToURL(browser(), url1_);
1311 content::NavigationController* controller =
1312 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1313 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1314 std::string session_storage_persistent_id =
1315 controller->GetDefaultSessionStorageNamespace()->persistent_id();
1316 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1317 ASSERT_EQ(1u, active_browser_list_->size());
1318 ASSERT_EQ(url1_,
1319 new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
1320 content::NavigationController* new_controller =
1321 &new_browser->tab_strip_model()->GetActiveWebContents()->GetController();
1322 ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace());
1323 std::string restored_session_storage_persistent_id =
1324 new_controller->GetDefaultSessionStorageNamespace()->persistent_id();
1325 EXPECT_EQ(session_storage_persistent_id,
1326 restored_session_storage_persistent_id);
1329 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) {
1330 // Simulate what prerendering does: create a new WebContents with the same
1331 // SessionStorageNamespace as an existing tab, then replace the tab with it.
1333 content::NavigationController* controller =
1334 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1335 ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
1337 content::SessionStorageNamespaceMap session_storage_namespace_map;
1338 session_storage_namespace_map[std::string()] =
1339 controller->GetDefaultSessionStorageNamespace();
1340 scoped_ptr<content::WebContents> web_contents(
1341 content::WebContents::CreateWithSessionStorage(
1342 content::WebContents::CreateParams(browser()->profile()),
1343 session_storage_namespace_map));
1345 TabStripModel* tab_strip_model = browser()->tab_strip_model();
1346 scoped_ptr<content::WebContents> old_web_contents(
1347 tab_strip_model->ReplaceWebContentsAt(
1348 tab_strip_model->active_index(), web_contents.release()));
1349 // Navigate with the new tab.
1350 ui_test_utils::NavigateToURL(browser(), url2_);
1351 // old_web_contents goes out of scope.
1354 // Check that the sessionStorage data is going to be persisted.
1355 content::NavigationController* controller =
1356 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
1357 EXPECT_TRUE(
1358 controller->GetDefaultSessionStorageNamespace()->should_persist());
1360 // Quit and restore. Check that no extra tabs were created.
1361 Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
1362 ASSERT_EQ(1u, active_browser_list_->size());
1363 EXPECT_EQ(1, new_browser->tab_strip_model()->count());
1366 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreSimpleTest, CorrectLoadingOrder) {
1367 ASSERT_EQ(SessionRestore::SMART_RESTORE_MODE_SIMPLE,
1368 SessionRestore::GetSmartRestoreMode());
1370 // Start observing the loading of tabs, to make sure the order is correct.
1371 StartObserving(kExpectedNumTabs);
1373 struct TabInfo {
1374 GURL url;
1375 bool pinned;
1376 int expected_load_order;
1379 TabInfo tab_info[kExpectedNumTabs] = {
1380 // This will be the foreground tab and will always load first.
1381 {GURL("http://google.com/1"), false, 1},
1382 {GURL("http://google.com/2"), false, 3},
1383 // Internal page, should load last.
1384 {GURL(chrome::kChromeUINewTabURL), false, 6},
1385 {GURL("http://google.com/4"), false, 4},
1386 {GURL("http://google.com/5"), true, 2}, // Pinned, should load second.
1387 {GURL("http://google.com/6"), false, 5},
1390 // Set up the restore data.
1391 std::vector<const sessions::SessionWindow*> session;
1392 sessions::SessionWindow window;
1393 sessions::SessionTab tab[kExpectedNumTabs];
1395 for (int i = 0; i < kExpectedNumTabs; i++) {
1396 SerializedNavigationEntry nav =
1397 SerializedNavigationEntryTestHelper::CreateNavigation(
1398 tab_info[i].url.spec(), tab_info[i].url.spec().c_str());
1399 sync_pb::SessionTab sync_data;
1400 sync_data.set_tab_visual_index(0);
1401 sync_data.set_current_navigation_index(0);
1402 sync_data.add_navigation()->CopyFrom(nav.ToSyncData());
1403 sync_data.set_pinned(tab_info[i].pinned);
1404 tab[i].SetFromSyncData(sync_data, base::Time::Now());
1405 window.tabs.push_back(tab + i);
1408 session.push_back(&window);
1409 Profile* profile = browser()->profile();
1410 std::vector<Browser*> browsers = SessionRestore::RestoreForeignSessionWindows(
1411 profile, browser()->host_desktop_type(), session.begin(), session.end());
1413 ASSERT_EQ(1u, browsers.size());
1414 ASSERT_TRUE(browsers[0]);
1415 ASSERT_EQ(kExpectedNumTabs, browsers[0]->tab_strip_model()->count());
1417 WaitForAllTabsToStartLoading();
1419 ASSERT_EQ(static_cast<size_t>(kExpectedNumTabs), web_contents().size());
1421 // Make sure that contents are loaded in the correct order, ie. each tab rank
1422 // is higher that its preceding one.
1423 std::map<GURL, int> ranks;
1424 for (auto t : tab_info)
1425 ranks[t.url] = t.expected_load_order;
1426 for (size_t i = 1; i < web_contents().size(); i++) {
1427 int current_rank = ranks[web_contents()[i]->GetLastCommittedURL()];
1428 int previous_rank = ranks[web_contents()[i - 1]->GetLastCommittedURL()];
1429 ASSERT_LT(previous_rank, current_rank);
1432 // The SessionWindow destructor deletes the tabs, so we have to clear them
1433 // here to avoid a crash.
1434 window.tabs.clear();
1437 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreMRUTest, PRE_CorrectLoadingOrder) {
1438 Profile* profile = browser()->profile();
1440 int activation_order[] = {4, 2, 1, 5, 0, 3};
1442 // Replace the first tab and add the other tabs.
1443 ui_test_utils::NavigateToURL(browser(), GURL(kUrls[0]));
1444 for (int i = 1; i < kExpectedNumTabs; i++) {
1445 ui_test_utils::NavigateToURLWithDisposition(
1446 browser(), GURL(kUrls[i]), NEW_FOREGROUND_TAB,
1447 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1450 ASSERT_EQ(kExpectedNumTabs, browser()->tab_strip_model()->count());
1452 // Activate the tabs one by one following the random activation order.
1453 for (auto i : activation_order)
1454 browser()->tab_strip_model()->ActivateTabAt(i, true);
1456 // Close the browser.
1457 g_browser_process->AddRefModule();
1458 CloseBrowserSynchronously(browser());
1460 StartObserving(kExpectedNumTabs);
1462 // Create a new window, which should trigger session restore.
1463 ui_test_utils::BrowserAddedObserver window_observer;
1464 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
1465 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
1466 ASSERT_TRUE(new_browser != NULL);
1467 WaitForAllTabsToStartLoading();
1468 g_browser_process->ReleaseModule();
1470 ASSERT_EQ(static_cast<size_t>(kExpectedNumTabs), web_contents().size());
1471 // Test that we have observed the tabs being loaded in the inverse order of
1472 // their activation (MRU). Also validate that their last active time is in the
1473 // correct order.
1474 for (size_t i = 0; i < web_contents().size(); i++) {
1475 GURL expected_url = GURL(kUrls[activation_order[kExpectedNumTabs - i - 1]]);
1476 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL());
1477 if (i > 0) {
1478 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(),
1479 web_contents()[i]->GetLastActiveTime());
1483 // Activate the 2nd tab before the browser closes. This should be persisted in
1484 // the following test.
1485 new_browser->tab_strip_model()->ActivateTabAt(1, true);
1488 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreMRUTest, CorrectLoadingOrder) {
1489 int activation_order[] = {4, 2, 5, 0, 3, 1};
1490 Profile* profile = browser()->profile();
1492 // Close the browser that gets opened automatically so we can track the order
1493 // of loading of the tabs.
1494 g_browser_process->AddRefModule();
1495 CloseBrowserSynchronously(browser());
1496 // We have an extra tab that is added when the test starts, which gets ignored
1497 // later when we test for proper order.
1498 StartObserving(kExpectedNumTabs + 1);
1500 // Create a new window, which should trigger session restore.
1501 ui_test_utils::BrowserAddedObserver window_observer;
1502 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
1503 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
1504 ASSERT_TRUE(new_browser != NULL);
1505 WaitForAllTabsToStartLoading();
1506 g_browser_process->ReleaseModule();
1508 ASSERT_EQ(static_cast<size_t>(kExpectedNumTabs + 1), web_contents().size());
1510 // Test that we have observed the tabs being loaded in the inverse order of
1511 // their activation (MRU). Also validate that their last active time is in the
1512 // correct order.
1514 // Note that we ignore the first tab as it's an empty one that is added
1515 // automatically at the start of the test.
1516 for (size_t i = 1; i < web_contents().size(); i++) {
1517 GURL expected_url = GURL(kUrls[activation_order[kExpectedNumTabs - i]]);
1518 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL());
1519 if (i > 0) {
1520 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(),
1521 web_contents()[i]->GetLastActiveTime());