blob: b7e444d76ae84f1095dd57728058f957f25d1af3 [file] [log] [blame]
[email protected]e18b9c272012-04-11 17:32:501// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avib896c712015-12-26 02:10:435#include <stddef.h>
6
[email protected]e18b9c272012-04-11 17:32:507#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:528#include "base/files/file_path.h"
avib896c712015-12-26 02:10:439#include "base/macros.h"
[email protected]2e9369e2014-08-15 09:12:5310#include "base/run_loop.h"
[email protected]e309f312013-06-07 21:50:0811#include "base/strings/utf_string_conversions.h"
[email protected]e18b9c272012-04-11 17:32:5012#include "base/test/test_timeouts.h"
avib896c712015-12-26 02:10:4313#include "build/build_config.h"
[email protected]e18b9c272012-04-11 17:32:5014#include "chrome/app/chrome_command_ids.h"
[email protected]25ff0862013-07-12 00:59:0315#include "chrome/browser/chrome_notification_types.h"
mkolomd19beb52016-09-21 08:10:3116#include "chrome/browser/lifetime/keep_alive_types.h"
17#include "chrome/browser/lifetime/scoped_keep_alive.h"
18#include "chrome/browser/prefs/session_startup_pref.h"
19#include "chrome/browser/sessions/session_restore_test_helper.h"
[email protected]2e9369e2014-08-15 09:12:5320#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]e18b9c272012-04-11 17:32:5021#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1022#include "chrome/browser/ui/browser_commands.h"
[email protected]abcfa65a2013-02-21 20:13:5823#include "chrome/browser/ui/browser_list.h"
blundell3d9313712016-07-20 09:15:3224#include "chrome/browser/ui/browser_live_tab_context.h"
[email protected]52877dbc62012-06-29 22:22:0325#include "chrome/browser/ui/browser_tabstrip.h"
[email protected]e18b9c272012-04-11 17:32:5026#include "chrome/browser/ui/find_bar/find_notification_details.h"
[email protected]81ddd3402012-12-28 00:55:2627#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]e18b9c272012-04-11 17:32:5028#include "chrome/common/chrome_paths.h"
29#include "chrome/common/url_constants.h"
30#include "chrome/test/base/in_process_browser_test.h"
31#include "chrome/test/base/ui_test_utils.h"
blundella08c5dd2015-09-18 06:14:1632#include "components/sessions/core/tab_restore_service.h"
33#include "components/sessions/core/tab_restore_service_observer.h"
[email protected]e18b9c272012-04-11 17:32:5034#include "content/public/browser/navigation_controller.h"
35#include "content/public/browser/notification_service.h"
36#include "content/public/browser/notification_source.h"
37#include "content/public/browser/notification_types.h"
38#include "content/public/browser/page_navigator.h"
39#include "content/public/browser/render_view_host.h"
40#include "content/public/browser/web_contents.h"
[email protected]13c526cc2013-10-17 05:51:3841#include "content/public/test/browser_test_utils.h"
[email protected]c1dffe82013-06-26 20:59:0542#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]761fa4702013-07-02 15:25:1543#include "url/gurl.h"
[email protected]e18b9c272012-04-11 17:32:5044
[email protected]2e9369e2014-08-15 09:12:5345// Class used to run a message loop waiting for the TabRestoreService to finish
46// loading. Does nothing if the TabRestoreService was already loaded.
blundell74001adc2015-09-18 11:04:2547class WaitForLoadObserver : public sessions::TabRestoreServiceObserver {
[email protected]2e9369e2014-08-15 09:12:5348 public:
49 explicit WaitForLoadObserver(Browser* browser)
50 : tab_restore_service_(
51 TabRestoreServiceFactory::GetForProfile(browser->profile())),
52 do_wait_(!tab_restore_service_->IsLoaded()) {
53 if (do_wait_)
54 tab_restore_service_->AddObserver(this);
55 }
56
Daniel Chenga542fca2014-10-21 09:51:2957 ~WaitForLoadObserver() override {
[email protected]2e9369e2014-08-15 09:12:5358 if (do_wait_)
59 tab_restore_service_->RemoveObserver(this);
60 }
61
62 void Wait() {
63 if (do_wait_)
64 run_loop_.Run();
65 }
66
67 private:
68 // Overridden from TabRestoreServiceObserver:
blundell74001adc2015-09-18 11:04:2569 void TabRestoreServiceChanged(sessions::TabRestoreService* service) override {
70 }
71 void TabRestoreServiceDestroyed(
72 sessions::TabRestoreService* service) override {}
73 void TabRestoreServiceLoaded(sessions::TabRestoreService* service) override {
[email protected]2e9369e2014-08-15 09:12:5374 DCHECK(do_wait_);
75 run_loop_.Quit();
76 }
77
blundell74001adc2015-09-18 11:04:2578 sessions::TabRestoreService* tab_restore_service_;
[email protected]2e9369e2014-08-15 09:12:5379 const bool do_wait_;
80 base::RunLoop run_loop_;
81
82 DISALLOW_COPY_AND_ASSIGN(WaitForLoadObserver);
83};
84
[email protected]e18b9c272012-04-11 17:32:5085class TabRestoreTest : public InProcessBrowserTest {
86 public:
[email protected]137fcfa22013-06-27 15:58:5787 TabRestoreTest() : active_browser_list_(NULL) {
[email protected]e18b9c272012-04-11 17:32:5088 url1_ = ui_test_utils::GetTestUrl(
[email protected]650b2d52013-02-10 03:41:4589 base::FilePath().AppendASCII("session_history"),
90 base::FilePath().AppendASCII("bot1.html"));
[email protected]e18b9c272012-04-11 17:32:5091 url2_ = ui_test_utils::GetTestUrl(
[email protected]650b2d52013-02-10 03:41:4592 base::FilePath().AppendASCII("session_history"),
93 base::FilePath().AppendASCII("bot2.html"));
[email protected]e18b9c272012-04-11 17:32:5094 }
95
96 protected:
Daniel Chenga542fca2014-10-21 09:51:2997 void SetUpOnMainThread() override {
scottmg0d8e4ab2016-01-28 00:34:5598 active_browser_list_ = BrowserList::GetInstance();
[email protected]137fcfa22013-06-27 15:58:5799 InProcessBrowserTest::SetUpOnMainThread();
100 }
101
[email protected]e18b9c272012-04-11 17:32:50102 Browser* GetBrowser(int index) {
[email protected]7d1a810b2013-06-26 19:51:59103 CHECK(static_cast<int>(active_browser_list_->size()) > index);
104 return active_browser_list_->get(index);
[email protected]e18b9c272012-04-11 17:32:50105 }
106
107 // Adds tabs to the given browser, all navigated to url1_. Returns
108 // the final number of tabs.
109 int AddSomeTabs(Browser* browser, int how_many) {
[email protected]ee496952013-01-10 23:17:33110 int starting_tab_count = browser->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50111
112 for (int i = 0; i < how_many; ++i) {
113 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19114 browser, url1_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50115 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
116 }
[email protected]ee496952013-01-10 23:17:33117 int tab_count = browser->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50118 EXPECT_EQ(starting_tab_count + how_many, tab_count);
119 return tab_count;
120 }
121
122 void CloseTab(int index) {
[email protected]13c526cc2013-10-17 05:51:38123 content::WebContentsDestroyedWatcher destroyed_watcher(
124 browser()->tab_strip_model()->GetWebContentsAt(index));
[email protected]81ddd3402012-12-28 00:55:26125 browser()->tab_strip_model()->CloseWebContentsAt(
126 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
[email protected]13c526cc2013-10-17 05:51:38127 destroyed_watcher.Wait();
[email protected]e18b9c272012-04-11 17:32:50128 }
129
130 // Uses the undo-close-tab accelerator to undo a close-tab or close-window
131 // operation. The newly restored tab is expected to appear in the
132 // window at index |expected_window_index|, at the |expected_tabstrip_index|,
133 // and to be active. If |expected_window_index| is equal to the number of
134 // current windows, the restored tab is expected to be created in a new
135 // window (since the index is 0-based).
[email protected]2e9369e2014-08-15 09:12:53136 void RestoreTab(int expected_window_index, int expected_tabstrip_index) {
[email protected]7d1a810b2013-06-26 19:51:59137 int window_count = static_cast<int>(active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50138 ASSERT_GT(window_count, 0);
139
140 bool expect_new_window = (expected_window_index == window_count);
141
142 Browser* browser;
143 if (expect_new_window) {
[email protected]7d1a810b2013-06-26 19:51:59144 browser = active_browser_list_->get(0);
[email protected]e18b9c272012-04-11 17:32:50145 } else {
146 browser = GetBrowser(expected_window_index);
147 }
[email protected]ee496952013-01-10 23:17:33148 int tab_count = browser->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50149 ASSERT_GT(tab_count, 0);
150
151 // Restore the tab.
[email protected]a7fe9112012-07-20 02:34:45152 content::WindowedNotificationObserver tab_added_observer(
153 chrome::NOTIFICATION_TAB_PARENTED,
154 content::NotificationService::AllSources());
155 content::WindowedNotificationObserver tab_loaded_observer(
156 content::NOTIFICATION_LOAD_STOP,
157 content::NotificationService::AllSources());
[email protected]2e9369e2014-08-15 09:12:53158 {
159 WaitForLoadObserver waiter(browser);
160 chrome::RestoreTab(browser);
161 waiter.Wait();
162 }
[email protected]e18b9c272012-04-11 17:32:50163 tab_added_observer.Wait();
164 tab_loaded_observer.Wait();
165
166 if (expect_new_window) {
[email protected]7d1a810b2013-06-26 19:51:59167 int new_window_count = static_cast<int>(active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50168 EXPECT_EQ(++window_count, new_window_count);
169 browser = GetBrowser(expected_window_index);
170 } else {
[email protected]ee496952013-01-10 23:17:33171 EXPECT_EQ(++tab_count, browser->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50172 }
173
174 // Get a handle to the restored tab.
[email protected]ee496952013-01-10 23:17:33175 ASSERT_GT(browser->tab_strip_model()->count(), expected_tabstrip_index);
[email protected]e18b9c272012-04-11 17:32:50176
177 // Ensure that the tab and window are active.
[email protected]ee496952013-01-10 23:17:33178 EXPECT_EQ(expected_tabstrip_index,
179 browser->tab_strip_model()->active_index());
[email protected]e18b9c272012-04-11 17:32:50180 }
181
182 void GoBack(Browser* browser) {
[email protected]a7fe9112012-07-20 02:34:45183 content::WindowedNotificationObserver observer(
[email protected]e18b9c272012-04-11 17:32:50184 content::NOTIFICATION_LOAD_STOP,
185 content::NotificationService::AllSources());
nick3b04f322016-08-31 19:29:19186 chrome::GoBack(browser, WindowOpenDisposition::CURRENT_TAB);
[email protected]e18b9c272012-04-11 17:32:50187 observer.Wait();
188 }
189
190 void EnsureTabFinishedRestoring(content::WebContents* tab) {
191 content::NavigationController* controller = &tab->GetController();
192 if (!controller->NeedsReload() && !controller->GetPendingEntry() &&
193 !controller->GetWebContents()->IsLoading())
194 return;
195
[email protected]a7fe9112012-07-20 02:34:45196 content::WindowedNotificationObserver observer(
[email protected]e18b9c272012-04-11 17:32:50197 content::NOTIFICATION_LOAD_STOP,
198 content::Source<content::NavigationController>(controller));
199 observer.Wait();
200 }
201
202 GURL url1_;
203 GURL url2_;
204
[email protected]7d1a810b2013-06-26 19:51:59205 const BrowserList* active_browser_list_;
[email protected]bc44f4142013-02-12 06:15:56206
[email protected]e18b9c272012-04-11 17:32:50207 private:
208 DISALLOW_COPY_AND_ASSIGN(TabRestoreTest);
209};
210
211// Close the end tab in the current window, then restore it. The tab should be
212// in its original position, and active.
213IN_PROC_BROWSER_TEST_F(TabRestoreTest, Basic) {
[email protected]ee496952013-01-10 23:17:33214 int starting_tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50215 int tab_count = AddSomeTabs(browser(), 1);
216
217 int closed_tab_index = tab_count - 1;
218 CloseTab(closed_tab_index);
[email protected]ee496952013-01-10 23:17:33219 EXPECT_EQ(starting_tab_count, browser()->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50220
221 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, closed_tab_index));
222
223 // And make sure everything looks right.
[email protected]ee496952013-01-10 23:17:33224 EXPECT_EQ(starting_tab_count + 1, browser()->tab_strip_model()->count());
225 EXPECT_EQ(closed_tab_index, browser()->tab_strip_model()->active_index());
226 EXPECT_EQ(url1_,
227 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50228}
229
230// Close a tab not at the end of the current window, then restore it. The tab
231// should be in its original position, and active.
232IN_PROC_BROWSER_TEST_F(TabRestoreTest, MiddleTab) {
[email protected]ee496952013-01-10 23:17:33233 int starting_tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50234 AddSomeTabs(browser(), 3);
235
236 // Close one in the middle
237 int closed_tab_index = starting_tab_count + 1;
238 CloseTab(closed_tab_index);
[email protected]ee496952013-01-10 23:17:33239 EXPECT_EQ(starting_tab_count + 2, browser()->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50240
241 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, closed_tab_index));
242
243 // And make sure everything looks right.
[email protected]ee496952013-01-10 23:17:33244 EXPECT_EQ(starting_tab_count + 3, browser()->tab_strip_model()->count());
245 EXPECT_EQ(closed_tab_index, browser()->tab_strip_model()->active_index());
246 EXPECT_EQ(url1_,
247 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50248}
249
250// Close a tab, switch windows, then restore the tab. The tab should be in its
251// original window and position, and active.
252IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreToDifferentWindow) {
[email protected]ee496952013-01-10 23:17:33253 int starting_tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50254 AddSomeTabs(browser(), 3);
255
256 // Close one in the middle
257 int closed_tab_index = starting_tab_count + 1;
258 CloseTab(closed_tab_index);
[email protected]ee496952013-01-10 23:17:33259 EXPECT_EQ(starting_tab_count + 2, browser()->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50260
261 // Create a new browser.
262 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19263 browser(), GURL(chrome::kChromeUINewTabURL),
264 WindowOpenDisposition::NEW_WINDOW,
[email protected]e18b9c272012-04-11 17:32:50265 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]7d1a810b2013-06-26 19:51:59266 EXPECT_EQ(2u, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50267
268 // Restore tab into original browser.
269 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, closed_tab_index));
270
271 // And make sure everything looks right.
[email protected]ee496952013-01-10 23:17:33272 EXPECT_EQ(starting_tab_count + 3, browser()->tab_strip_model()->count());
273 EXPECT_EQ(closed_tab_index, browser()->tab_strip_model()->active_index());
274 EXPECT_EQ(url1_,
275 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50276}
277
278// Close a tab, open a new window, close the first window, then restore the
279// tab. It should be in a new window.
280// If this becomes flaky, use http://crbug.com/14774
[email protected]1e09ec82012-12-21 22:48:09281IN_PROC_BROWSER_TEST_F(TabRestoreTest, DISABLED_BasicRestoreFromClosedWindow) {
[email protected]e18b9c272012-04-11 17:32:50282 // Navigate to url1 then url2.
283 ui_test_utils::NavigateToURL(browser(), url1_);
284 ui_test_utils::NavigateToURL(browser(), url2_);
285
286 // Create a new browser.
287 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19288 browser(), GURL(chrome::kChromeUINewTabURL),
289 WindowOpenDisposition::NEW_WINDOW,
[email protected]e18b9c272012-04-11 17:32:50290 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]7d1a810b2013-06-26 19:51:59291 EXPECT_EQ(2u, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50292
293 // Close the final tab in the first browser.
[email protected]a7fe9112012-07-20 02:34:45294 content::WindowedNotificationObserver window_observer(
[email protected]e18b9c272012-04-11 17:32:50295 chrome::NOTIFICATION_BROWSER_CLOSED,
296 content::NotificationService::AllSources());
297 CloseTab(0);
298 window_observer.Wait();
299
300 ASSERT_NO_FATAL_FAILURE(RestoreTab(1, 0));
301
302 // Tab should be in a new window.
303 Browser* browser = GetBrowser(1);
[email protected]ee496952013-01-10 23:17:33304 content::WebContents* web_contents =
305 browser->tab_strip_model()->GetActiveWebContents();
306 // And make sure the URLs match.
[email protected]e18b9c272012-04-11 17:32:50307 EXPECT_EQ(url2_, web_contents->GetURL());
308 GoBack(browser);
309 EXPECT_EQ(url1_, web_contents->GetURL());
310}
311
[email protected]3f3494f32013-01-22 21:10:08312#if defined(OS_WIN)
313// Flakily times out: http://crbug.com/171503
314#define MAYBE_DontLoadRestoredTab DISABLED_DontLoadRestoredTab
315#else
316#define MAYBE_DontLoadRestoredTab DontLoadRestoredTab
317#endif
318
[email protected]e18b9c272012-04-11 17:32:50319// Restore a tab then make sure it doesn't restore again.
[email protected]3f3494f32013-01-22 21:10:08320IN_PROC_BROWSER_TEST_F(TabRestoreTest, MAYBE_DontLoadRestoredTab) {
[email protected]e18b9c272012-04-11 17:32:50321 // Add two tabs
[email protected]ee496952013-01-10 23:17:33322 int starting_tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50323 AddSomeTabs(browser(), 2);
[email protected]ee496952013-01-10 23:17:33324 ASSERT_EQ(browser()->tab_strip_model()->count(), starting_tab_count + 2);
[email protected]e18b9c272012-04-11 17:32:50325
326 // Close one of them.
327 CloseTab(0);
[email protected]ee496952013-01-10 23:17:33328 ASSERT_EQ(browser()->tab_strip_model()->count(), starting_tab_count + 1);
[email protected]e18b9c272012-04-11 17:32:50329
330 // Restore it.
331 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 0));
[email protected]ee496952013-01-10 23:17:33332 ASSERT_EQ(browser()->tab_strip_model()->count(), starting_tab_count + 2);
[email protected]e18b9c272012-04-11 17:32:50333
334 // Make sure that there's nothing else to restore.
[email protected]2bf6314b2013-02-20 03:51:14335 ASSERT_EQ(chrome::GetRestoreTabType(browser()),
336 TabStripModelDelegate::RESTORE_NONE);
[email protected]e18b9c272012-04-11 17:32:50337}
338
339// Open a window with multiple tabs, close a tab, then close the window.
340// Restore both and make sure the tab goes back into the window.
341IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreWindowAndTab) {
[email protected]ee496952013-01-10 23:17:33342 int starting_tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50343 AddSomeTabs(browser(), 3);
344
345 // Close one in the middle
346 int closed_tab_index = starting_tab_count + 1;
347 CloseTab(closed_tab_index);
[email protected]ee496952013-01-10 23:17:33348 EXPECT_EQ(starting_tab_count + 2, browser()->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50349
350 // Create a new browser.
351 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19352 browser(), GURL(chrome::kChromeUINewTabURL),
353 WindowOpenDisposition::NEW_WINDOW,
[email protected]e18b9c272012-04-11 17:32:50354 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]7d1a810b2013-06-26 19:51:59355 EXPECT_EQ(2u, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50356
357 // Close the first browser.
[email protected]a7fe9112012-07-20 02:34:45358 content::WindowedNotificationObserver observer(
[email protected]e18b9c272012-04-11 17:32:50359 chrome::NOTIFICATION_BROWSER_CLOSED,
360 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10361 chrome::CloseWindow(browser());
[email protected]e18b9c272012-04-11 17:32:50362 observer.Wait();
[email protected]7d1a810b2013-06-26 19:51:59363 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50364
365 // Restore the first window. The expected_tabstrip_index (second argument)
366 // indicates the expected active tab.
367 ASSERT_NO_FATAL_FAILURE(RestoreTab(1, starting_tab_count + 1));
368 Browser* browser = GetBrowser(1);
[email protected]ee496952013-01-10 23:17:33369 EXPECT_EQ(starting_tab_count + 2, browser->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50370
371 // Restore the closed tab.
372 ASSERT_NO_FATAL_FAILURE(RestoreTab(1, closed_tab_index));
[email protected]ee496952013-01-10 23:17:33373 EXPECT_EQ(starting_tab_count + 3, browser->tab_strip_model()->count());
374 EXPECT_EQ(url1_,
375 browser->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50376}
377
378// Open a window with two tabs, close both (closing the window), then restore
379// both. Make sure both restored tabs are in the same window.
380IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreIntoSameWindow) {
381 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19382 browser(), url1_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50383 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
384 // Navigate the rightmost one to url2_ for easier identification.
385 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19386 browser(), url2_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50387 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
388
389 // Create a new browser.
390 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19391 browser(), GURL(chrome::kChromeUINewTabURL),
392 WindowOpenDisposition::NEW_WINDOW,
[email protected]e18b9c272012-04-11 17:32:50393 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]7d1a810b2013-06-26 19:51:59394 EXPECT_EQ(2u, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50395
396 // Close all but one tab in the first browser, left to right.
[email protected]ee496952013-01-10 23:17:33397 while (browser()->tab_strip_model()->count() > 1)
[email protected]e18b9c272012-04-11 17:32:50398 CloseTab(0);
399
400 // Close the last tab, closing the browser.
[email protected]a7fe9112012-07-20 02:34:45401 content::WindowedNotificationObserver observer(
[email protected]e18b9c272012-04-11 17:32:50402 chrome::NOTIFICATION_BROWSER_CLOSED,
403 content::NotificationService::AllSources());
404 CloseTab(0);
405 observer.Wait();
[email protected]7d1a810b2013-06-26 19:51:59406 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50407
408 // Restore the last-closed tab into a new window.
409 ASSERT_NO_FATAL_FAILURE(RestoreTab(1, 0));
410 Browser* browser = GetBrowser(1);
[email protected]ee496952013-01-10 23:17:33411 EXPECT_EQ(1, browser->tab_strip_model()->count());
412 EXPECT_EQ(url2_,
413 browser->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50414
415 // Restore the next-to-last-closed tab into the same window.
416 ASSERT_NO_FATAL_FAILURE(RestoreTab(1, 0));
[email protected]ee496952013-01-10 23:17:33417 EXPECT_EQ(2, browser->tab_strip_model()->count());
418 EXPECT_EQ(url1_,
419 browser->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50420}
421
blundell3d9313712016-07-20 09:15:32422// Open a window with two tabs, close both (closing the window), then restore
423// one by ID. Guards against regression of crbug.com/622752.
424IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreTabFromClosedWindowByID) {
425 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19426 browser(), url1_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
blundell3d9313712016-07-20 09:15:32427 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
428 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19429 browser(), url2_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
blundell3d9313712016-07-20 09:15:32430 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
431
432 // Create a new browser.
433 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19434 browser(), GURL(chrome::kChromeUINewTabURL),
435 WindowOpenDisposition::NEW_WINDOW,
blundell3d9313712016-07-20 09:15:32436 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
437 EXPECT_EQ(2u, active_browser_list_->size());
438
439 // Close the window.
440 content::WindowedNotificationObserver close_window_observer(
441 chrome::NOTIFICATION_BROWSER_CLOSED,
442 content::NotificationService::AllSources());
443 chrome::CloseWindow(browser());
444 close_window_observer.Wait();
445 EXPECT_EQ(1u, active_browser_list_->size());
446
447 // Check that the TabRestoreService has the contents of the closed window.
448 Browser* browser = GetBrowser(0);
449 sessions::TabRestoreService* service =
450 TabRestoreServiceFactory::GetForProfile(browser->profile());
451 const sessions::TabRestoreService::Entries& entries = service->entries();
452 EXPECT_EQ(1u, entries.size());
sdy7710d22c2016-08-09 14:04:34453 sessions::TabRestoreService::Entry* entry = entries.front().get();
blundell3d9313712016-07-20 09:15:32454 ASSERT_EQ(sessions::TabRestoreService::WINDOW, entry->type);
455 sessions::TabRestoreService::Window* entry_win =
456 static_cast<sessions::TabRestoreService::Window*>(entry);
sdy7710d22c2016-08-09 14:04:34457 auto& tabs = entry_win->tabs;
blundell3d9313712016-07-20 09:15:32458 EXPECT_EQ(3u, tabs.size());
459
460 // Find the Tab to restore.
sdy7710d22c2016-08-09 14:04:34461 SessionID::id_type tab_id_to_restore = 0;
blundell3d9313712016-07-20 09:15:32462 bool found_tab_to_restore = false;
sdy7710d22c2016-08-09 14:04:34463 for (const auto& tab_ptr : tabs) {
464 auto& tab = *tab_ptr;
blundell3d9313712016-07-20 09:15:32465 if (tab.navigations[tab.current_navigation_index].virtual_url() == url1_) {
sdy7710d22c2016-08-09 14:04:34466 tab_id_to_restore = tab.id;
blundell3d9313712016-07-20 09:15:32467 found_tab_to_restore = true;
468 break;
469 }
470 }
471 ASSERT_TRUE(found_tab_to_restore);
472
473 // Restore the tab into the current window.
474 EXPECT_EQ(1, browser->tab_strip_model()->count());
475 content::WindowedNotificationObserver tab_added_observer(
476 chrome::NOTIFICATION_TAB_PARENTED,
477 content::NotificationService::AllSources());
478 content::WindowedNotificationObserver tab_loaded_observer(
479 content::NOTIFICATION_LOAD_STOP,
480 content::NotificationService::AllSources());
sdy7710d22c2016-08-09 14:04:34481 service->RestoreEntryById(browser->live_tab_context(), tab_id_to_restore,
nick3b04f322016-08-31 19:29:19482 WindowOpenDisposition::NEW_FOREGROUND_TAB);
blundell3d9313712016-07-20 09:15:32483 tab_added_observer.Wait();
484 tab_loaded_observer.Wait();
485
486 // Check that the tab was correctly restored.
487 EXPECT_EQ(2, browser->tab_strip_model()->count());
488 EXPECT_EQ(url1_,
489 browser->tab_strip_model()->GetActiveWebContents()->GetURL());
490}
491
[email protected]e18b9c272012-04-11 17:32:50492// Tests that a duplicate history entry is not created when we restore a page
493// to an existing SiteInstance. (Bug 1230446)
494IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreWithExistingSiteInstance) {
svaldeza01f7d92015-11-18 17:47:56495 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]e18b9c272012-04-11 17:32:50496
[email protected]c1dffe82013-06-26 20:59:05497 GURL http_url1(embedded_test_server()->GetURL("/title1.html"));
498 GURL http_url2(embedded_test_server()->GetURL("/title2.html"));
[email protected]ee496952013-01-10 23:17:33499 int tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50500
501 // Add a tab
502 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19503 browser(), http_url1, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50504 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]ee496952013-01-10 23:17:33505 EXPECT_EQ(++tab_count, browser()->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50506
507 // Navigate to another same-site URL.
[email protected]52877dbc62012-06-29 22:22:03508 content::WebContents* tab =
[email protected]ee496952013-01-10 23:17:33509 browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
[email protected]a7fe9112012-07-20 02:34:45510 content::WindowedNotificationObserver observer(
[email protected]e18b9c272012-04-11 17:32:50511 content::NOTIFICATION_LOAD_STOP,
512 content::NotificationService::AllSources());
513 static_cast<content::WebContentsDelegate*>(browser())->OpenURLFromTab(
nick3b04f322016-08-31 19:29:19514 tab, content::OpenURLParams(http_url2, content::Referrer(),
515 WindowOpenDisposition::CURRENT_TAB,
516 ui::PAGE_TRANSITION_TYPED, false));
[email protected]e18b9c272012-04-11 17:32:50517 observer.Wait();
518
519 // Close the tab.
520 CloseTab(1);
521
522 // Create a new tab to the original site. Assuming process-per-site is
523 // enabled, this will ensure that the SiteInstance used by the restored tab
524 // will already exist when the restore happens.
525 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19526 browser(), http_url2, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50527 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
528
529 // Restore the closed tab.
530 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, tab_count - 1));
531
532 // And make sure the URLs match.
[email protected]ee496952013-01-10 23:17:33533 EXPECT_EQ(http_url2,
534 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50535 GoBack(browser());
[email protected]ee496952013-01-10 23:17:33536 EXPECT_EQ(http_url1,
537 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50538}
539
[email protected]986aa782013-06-11 20:19:18540// See crbug.com/248574
541#if defined(OS_WIN)
scottmg0d8e4ab2016-01-28 00:34:55542#define MAYBE_RestoreCrossSiteWithExistingSiteInstance \
543 DISABLED_RestoreCrossSiteWithExistingSiteInstance
[email protected]986aa782013-06-11 20:19:18544#else
scottmg0d8e4ab2016-01-28 00:34:55545#define MAYBE_RestoreCrossSiteWithExistingSiteInstance \
546 RestoreCrossSiteWithExistingSiteInstance
[email protected]986aa782013-06-11 20:19:18547#endif
548
[email protected]e18b9c272012-04-11 17:32:50549// Tests that the SiteInstances used for entries in a restored tab's history
550// are given appropriate max page IDs, even if the renderer for the entry
551// already exists. (Bug 1204135)
552IN_PROC_BROWSER_TEST_F(TabRestoreTest,
[email protected]986aa782013-06-11 20:19:18553 MAYBE_RestoreCrossSiteWithExistingSiteInstance) {
svaldeza01f7d92015-11-18 17:47:56554 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]e18b9c272012-04-11 17:32:50555
[email protected]c1dffe82013-06-26 20:59:05556 GURL http_url1(embedded_test_server()->GetURL("/title1.html"));
557 GURL http_url2(embedded_test_server()->GetURL("/title2.html"));
[email protected]e18b9c272012-04-11 17:32:50558
[email protected]ee496952013-01-10 23:17:33559 int tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50560
561 // Add a tab
562 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19563 browser(), http_url1, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50564 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]ee496952013-01-10 23:17:33565 EXPECT_EQ(++tab_count, browser()->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50566
567 // Navigate to more URLs, then a cross-site URL.
thestig53986dc2014-12-16 06:09:18568 ui_test_utils::NavigateToURL(browser(), http_url2);
569 ui_test_utils::NavigateToURL(browser(), http_url1);
570 ui_test_utils::NavigateToURL(browser(), url1_);
[email protected]e18b9c272012-04-11 17:32:50571
572 // Close the tab.
573 CloseTab(1);
574
575 // Create a new tab to the original site. Assuming process-per-site is
576 // enabled, this will ensure that the SiteInstance will already exist when
577 // the user clicks Back in the restored tab.
578 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19579 browser(), http_url2, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50580 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
581
582 // Restore the closed tab.
583 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, tab_count - 1));
584
585 // And make sure the URLs match.
[email protected]ee496952013-01-10 23:17:33586 EXPECT_EQ(url1_,
587 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50588 GoBack(browser());
[email protected]ee496952013-01-10 23:17:33589 EXPECT_EQ(http_url1,
590 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50591
592 // Navigating to a new URL should clear the forward list, because the max
593 // page ID of the renderer should have been updated when we restored the tab.
thestig53986dc2014-12-16 06:09:18594 ui_test_utils::NavigateToURL(browser(), http_url2);
[email protected]a37d4b02012-06-25 21:56:10595 EXPECT_FALSE(chrome::CanGoForward(browser()));
[email protected]ee496952013-01-10 23:17:33596 EXPECT_EQ(http_url2,
597 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
[email protected]e18b9c272012-04-11 17:32:50598}
599
600IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreWindow) {
601 // Create a new window.
[email protected]7d1a810b2013-06-26 19:51:59602 size_t window_count = active_browser_list_->size();
[email protected]e18b9c272012-04-11 17:32:50603 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19604 browser(), GURL(chrome::kChromeUINewTabURL),
605 WindowOpenDisposition::NEW_WINDOW,
[email protected]e18b9c272012-04-11 17:32:50606 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
[email protected]7d1a810b2013-06-26 19:51:59607 EXPECT_EQ(++window_count, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50608
609 // Create two more tabs, one with url1, the other url2.
[email protected]ee496952013-01-10 23:17:33610 int initial_tab_count = browser()->tab_strip_model()->count();
[email protected]e18b9c272012-04-11 17:32:50611 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19612 browser(), url1_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50613 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
614 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19615 browser(), url2_, WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50616 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
617
618 // Close the window.
[email protected]a7fe9112012-07-20 02:34:45619 content::WindowedNotificationObserver close_window_observer(
[email protected]e18b9c272012-04-11 17:32:50620 chrome::NOTIFICATION_BROWSER_CLOSED,
621 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10622 chrome::CloseWindow(browser());
[email protected]e18b9c272012-04-11 17:32:50623 close_window_observer.Wait();
[email protected]7d1a810b2013-06-26 19:51:59624 EXPECT_EQ(window_count - 1, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50625
626 // Restore the window.
[email protected]a7fe9112012-07-20 02:34:45627 content::WindowedNotificationObserver open_window_observer(
[email protected]e18b9c272012-04-11 17:32:50628 chrome::NOTIFICATION_BROWSER_OPENED,
629 content::NotificationService::AllSources());
[email protected]a7fe9112012-07-20 02:34:45630 content::WindowedNotificationObserver load_stop_observer(
[email protected]e18b9c272012-04-11 17:32:50631 content::NOTIFICATION_LOAD_STOP,
632 content::NotificationService::AllSources());
[email protected]7d1a810b2013-06-26 19:51:59633 chrome::RestoreTab(active_browser_list_->get(0));
[email protected]e18b9c272012-04-11 17:32:50634 open_window_observer.Wait();
[email protected]7d1a810b2013-06-26 19:51:59635 EXPECT_EQ(window_count, active_browser_list_->size());
[email protected]e18b9c272012-04-11 17:32:50636
637 Browser* browser = GetBrowser(1);
[email protected]ee496952013-01-10 23:17:33638 EXPECT_EQ(initial_tab_count + 2, browser->tab_strip_model()->count());
[email protected]e18b9c272012-04-11 17:32:50639 load_stop_observer.Wait();
640
641 content::WebContents* restored_tab =
[email protected]ee496952013-01-10 23:17:33642 browser->tab_strip_model()->GetWebContentsAt(initial_tab_count);
[email protected]e18b9c272012-04-11 17:32:50643 EnsureTabFinishedRestoring(restored_tab);
644 EXPECT_EQ(url1_, restored_tab->GetURL());
645
[email protected]ee496952013-01-10 23:17:33646 restored_tab =
647 browser->tab_strip_model()->GetWebContentsAt(initial_tab_count + 1);
[email protected]e18b9c272012-04-11 17:32:50648 EnsureTabFinishedRestoring(restored_tab);
649 EXPECT_EQ(url2_, restored_tab->GetURL());
650}
651
652// Restore tab with special URL chrome://credits/ and make sure the page loads
653// properly after restore. See http://crbug.com/31905.
654IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreTabWithSpecialURL) {
655 // Navigate new tab to a special URL.
656 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19657 browser(), GURL(chrome::kChromeUICreditsURL),
658 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50659 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
660
661 // Close the tab.
662 CloseTab(1);
663
664 // Restore the closed tab.
665 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 1));
[email protected]ee496952013-01-10 23:17:33666 content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]ba3d09a12012-11-07 12:13:52667 EnsureTabFinishedRestoring(tab);
[email protected]e18b9c272012-04-11 17:32:50668
669 // See if content is as expected.
670 EXPECT_GT(
[email protected]f911df52013-12-24 23:24:23671 ui_test_utils::FindInPage(tab, base::ASCIIToUTF16("webkit"), true, false,
672 NULL, NULL),
[email protected]e18b9c272012-04-11 17:32:50673 0);
674}
675
lukasza74cbd5d2016-11-23 18:34:02676// https://crbug.com/667932: Flakiness on linux_chromium_asan_rel_ng bot.
677#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
678#define MAYBE_RestoreTabWithSpecialURLOnBack DISABLED_RestoreTabWithSpecialURLOnBack
679#else
680#define MAYBE_RestoreTabWithSpecialURLOnBack RestoreTabWithSpecialURLOnBack
681#endif
682
[email protected]e18b9c272012-04-11 17:32:50683// Restore tab with special URL in its navigation history, go back to that
684// entry and see that it loads properly. See http://crbug.com/31905
lukasza74cbd5d2016-11-23 18:34:02685IN_PROC_BROWSER_TEST_F(TabRestoreTest, MAYBE_RestoreTabWithSpecialURLOnBack) {
svaldeza01f7d92015-11-18 17:47:56686 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]e18b9c272012-04-11 17:32:50687
[email protected]c1dffe82013-06-26 20:59:05688 const GURL http_url(embedded_test_server()->GetURL("/title1.html"));
[email protected]e18b9c272012-04-11 17:32:50689
690 // Navigate new tab to a special URL.
691 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19692 browser(), GURL(chrome::kChromeUICreditsURL),
693 WindowOpenDisposition::NEW_FOREGROUND_TAB,
[email protected]e18b9c272012-04-11 17:32:50694 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
695
696 // Then navigate to a normal URL.
697 ui_test_utils::NavigateToURL(browser(), http_url);
698
699 // Close the tab.
700 CloseTab(1);
701
702 // Restore the closed tab.
703 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 1));
[email protected]ee496952013-01-10 23:17:33704 content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]ba3d09a12012-11-07 12:13:52705 EnsureTabFinishedRestoring(tab);
706 ASSERT_EQ(http_url, tab->GetURL());
[email protected]e18b9c272012-04-11 17:32:50707
708 // Go back, and see if content is as expected.
709 GoBack(browser());
710 EXPECT_GT(
[email protected]f911df52013-12-24 23:24:23711 ui_test_utils::FindInPage(tab, base::ASCIIToUTF16("webkit"), true, false,
712 NULL, NULL),
[email protected]e18b9c272012-04-11 17:32:50713 0);
714}
[email protected]2e9369e2014-08-15 09:12:53715
716IN_PROC_BROWSER_TEST_F(TabRestoreTest, PRE_RestoreOnStartup) {
717 // This results in a new tab at the end with url1.
718 AddSomeTabs(browser(), 1);
719
720 while (browser()->tab_strip_model()->count())
721 CloseTab(0);
722}
723
724// Verifies restoring a tab works on startup.
725IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreOnStartup) {
726 ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 1));
727 EXPECT_EQ(url1_,
728 browser()->tab_strip_model()->GetWebContentsAt(1)->GetURL());
729}
mkolomd19beb52016-09-21 08:10:31730
731// Check that TabRestoreService and SessionService do not try to restore the
732// same thing.
733IN_PROC_BROWSER_TEST_F(TabRestoreTest,
734 RestoreFirstBrowserWhenSessionServiceEnabled) {
735 // Do not exit from test when last browser is closed.
736 ScopedKeepAlive keep_alive(KeepAliveOrigin::SESSION_RESTORE,
737 KeepAliveRestartOption::DISABLED);
738
739 // Enable session service.
740 SessionStartupPref pref(SessionStartupPref::LAST);
741 Profile* profile = browser()->profile();
742 SessionStartupPref::SetStartupPref(profile, pref);
743
744 // Add tabs and close browser.
745 AddSomeTabs(browser(), 3);
746 // 1st tab is about:blank added by InProcessBrowserTest.
747 EXPECT_EQ(4, browser()->tab_strip_model()->count());
748 content::WindowedNotificationObserver observer(
749 chrome::NOTIFICATION_BROWSER_CLOSED,
750 content::NotificationService::AllSources());
751 chrome::CloseWindow(browser());
752 observer.Wait();
753
754 SessionRestoreTestHelper helper;
755 // Restore browser (this is what Cmd-Shift-T does on Mac).
756 chrome::OpenWindowWithRestoredTabs(profile);
757 if (SessionRestore::IsRestoring(profile))
758 helper.Wait();
759 Browser* browser = GetBrowser(0);
760 EXPECT_EQ(4, browser->tab_strip_model()->count());
761}