1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "base/command_line.h"
7#include "base/files/file_path.h"
8#include "base/run_loop.h"
9#include "base/strings/utf_string_conversions.h"
10#include "base/test/test_timeouts.h"
11#include "chrome/app/chrome_command_ids.h"
12#include "chrome/browser/chrome_notification_types.h"
13#include "chrome/browser/sessions/tab_restore_service.h"
14#include "chrome/browser/sessions/tab_restore_service_factory.h"
15#include "chrome/browser/sessions/tab_restore_service_observer.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/browser_commands.h"
18#include "chrome/browser/ui/browser_list.h"
19#include "chrome/browser/ui/browser_tabstrip.h"
20#include "chrome/browser/ui/find_bar/find_notification_details.h"
21#include "chrome/browser/ui/tabs/tab_strip_model.h"
22#include "chrome/common/chrome_paths.h"
23#include "chrome/common/url_constants.h"
24#include "chrome/test/base/in_process_browser_test.h"
25#include "chrome/test/base/ui_test_utils.h"
26#include "content/public/browser/navigation_controller.h"
27#include "content/public/browser/notification_service.h"
28#include "content/public/browser/notification_source.h"
29#include "content/public/browser/notification_types.h"
30#include "content/public/browser/page_navigator.h"
31#include "content/public/browser/render_view_host.h"
32#include "content/public/browser/web_contents.h"
33#include "content/public/test/browser_test_utils.h"
34#include "net/base/net_util.h"
35#include "net/test/embedded_test_server/embedded_test_server.h"
36#include "third_party/WebKit/public/web/WebFindOptions.h"
37#include "url/gurl.h"
38
39// Class used to run a message loop waiting for the TabRestoreService to finish
40// loading. Does nothing if the TabRestoreService was already loaded.
41class WaitForLoadObserver : public TabRestoreServiceObserver {
42 public:
43  explicit WaitForLoadObserver(Browser* browser)
44      : tab_restore_service_(
45          TabRestoreServiceFactory::GetForProfile(browser->profile())),
46        do_wait_(!tab_restore_service_->IsLoaded()) {
47    if (do_wait_)
48      tab_restore_service_->AddObserver(this);
49  }
50
51  virtual ~WaitForLoadObserver() {
52    if (do_wait_)
53      tab_restore_service_->RemoveObserver(this);
54  }
55
56  void Wait() {
57    if (do_wait_)
58      run_loop_.Run();
59  }
60
61 private:
62  // Overridden from TabRestoreServiceObserver:
63  virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE {}
64  virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE {
65  }
66  virtual void TabRestoreServiceLoaded(TabRestoreService* service) OVERRIDE {
67    DCHECK(do_wait_);
68    run_loop_.Quit();
69  }
70
71  TabRestoreService* tab_restore_service_;
72  const bool do_wait_;
73  base::RunLoop run_loop_;
74
75  DISALLOW_COPY_AND_ASSIGN(WaitForLoadObserver);
76};
77
78class TabRestoreTest : public InProcessBrowserTest {
79 public:
80  TabRestoreTest() : active_browser_list_(NULL) {
81    url1_ = ui_test_utils::GetTestUrl(
82        base::FilePath().AppendASCII("session_history"),
83        base::FilePath().AppendASCII("bot1.html"));
84    url2_ = ui_test_utils::GetTestUrl(
85        base::FilePath().AppendASCII("session_history"),
86        base::FilePath().AppendASCII("bot2.html"));
87  }
88
89 protected:
90  virtual void SetUpOnMainThread() OVERRIDE {
91    active_browser_list_ = BrowserList::GetInstance(chrome::GetActiveDesktop());
92    InProcessBrowserTest::SetUpOnMainThread();
93  }
94
95  Browser* GetBrowser(int index) {
96    CHECK(static_cast<int>(active_browser_list_->size()) > index);
97    return active_browser_list_->get(index);
98  }
99
100  // Adds tabs to the given browser, all navigated to url1_. Returns
101  // the final number of tabs.
102  int AddSomeTabs(Browser* browser, int how_many) {
103    int starting_tab_count = browser->tab_strip_model()->count();
104
105    for (int i = 0; i < how_many; ++i) {
106      ui_test_utils::NavigateToURLWithDisposition(
107          browser, url1_, NEW_FOREGROUND_TAB,
108          ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
109    }
110    int tab_count = browser->tab_strip_model()->count();
111    EXPECT_EQ(starting_tab_count + how_many, tab_count);
112    return tab_count;
113  }
114
115  void CloseTab(int index) {
116    content::WebContentsDestroyedWatcher destroyed_watcher(
117        browser()->tab_strip_model()->GetWebContentsAt(index));
118    browser()->tab_strip_model()->CloseWebContentsAt(
119        index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
120    destroyed_watcher.Wait();
121  }
122
123  // Uses the undo-close-tab accelerator to undo a close-tab or close-window
124  // operation. The newly restored tab is expected to appear in the
125  // window at index |expected_window_index|, at the |expected_tabstrip_index|,
126  // and to be active. If |expected_window_index| is equal to the number of
127  // current windows, the restored tab is expected to be created in a new
128  // window (since the index is 0-based).
129  void RestoreTab(int expected_window_index, int expected_tabstrip_index) {
130    int window_count = static_cast<int>(active_browser_list_->size());
131    ASSERT_GT(window_count, 0);
132
133    bool expect_new_window = (expected_window_index == window_count);
134
135    Browser* browser;
136    if (expect_new_window) {
137      browser = active_browser_list_->get(0);
138    } else {
139      browser = GetBrowser(expected_window_index);
140    }
141    int tab_count = browser->tab_strip_model()->count();
142    ASSERT_GT(tab_count, 0);
143
144    // Restore the tab.
145    content::WindowedNotificationObserver tab_added_observer(
146        chrome::NOTIFICATION_TAB_PARENTED,
147        content::NotificationService::AllSources());
148    content::WindowedNotificationObserver tab_loaded_observer(
149        content::NOTIFICATION_LOAD_STOP,
150        content::NotificationService::AllSources());
151    {
152      WaitForLoadObserver waiter(browser);
153      chrome::RestoreTab(browser);
154      waiter.Wait();
155    }
156    tab_added_observer.Wait();
157    tab_loaded_observer.Wait();
158
159    if (expect_new_window) {
160      int new_window_count = static_cast<int>(active_browser_list_->size());
161      EXPECT_EQ(++window_count, new_window_count);
162      browser = GetBrowser(expected_window_index);
163    } else {
164      EXPECT_EQ(++tab_count, browser->tab_strip_model()->count());
165    }
166
167    // Get a handle to the restored tab.
168    ASSERT_GT(browser->tab_strip_model()->count(), expected_tabstrip_index);
169
170    // Ensure that the tab and window are active.
171    EXPECT_EQ(expected_tabstrip_index,
172              browser->tab_strip_model()->active_index());
173  }
174
175  void GoBack(Browser* browser) {
176    content::WindowedNotificationObserver observer(
177        content::NOTIFICATION_LOAD_STOP,
178        content::NotificationService::AllSources());
179    chrome::GoBack(browser, CURRENT_TAB);
180    observer.Wait();
181  }
182
183  void EnsureTabFinishedRestoring(content::WebContents* tab) {
184    content::NavigationController* controller = &tab->GetController();
185    if (!controller->NeedsReload() && !controller->GetPendingEntry() &&
186        !controller->GetWebContents()->IsLoading())
187      return;
188
189    content::WindowedNotificationObserver observer(
190        content::NOTIFICATION_LOAD_STOP,
191        content::Source<content::NavigationController>(controller));
192    observer.Wait();
193  }
194
195  GURL url1_;
196  GURL url2_;
197
198  const BrowserList* active_browser_list_;
199
200 private:
201  DISALLOW_COPY_AND_ASSIGN(TabRestoreTest);
202};
203
204// Close the end tab in the current window, then restore it. The tab should be
205// in its original position, and active.
206IN_PROC_BROWSER_TEST_F(TabRestoreTest, Basic) {
207  int starting_tab_count = browser()->tab_strip_model()->count();
208  int tab_count = AddSomeTabs(browser(), 1);
209
210  int closed_tab_index = tab_count - 1;
211  CloseTab(closed_tab_index);
212  EXPECT_EQ(starting_tab_count, browser()->tab_strip_model()->count());
213
214  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, closed_tab_index));
215
216  // And make sure everything looks right.
217  EXPECT_EQ(starting_tab_count + 1, browser()->tab_strip_model()->count());
218  EXPECT_EQ(closed_tab_index, browser()->tab_strip_model()->active_index());
219  EXPECT_EQ(url1_,
220            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
221}
222
223// Close a tab not at the end of the current window, then restore it. The tab
224// should be in its original position, and active.
225IN_PROC_BROWSER_TEST_F(TabRestoreTest, MiddleTab) {
226  int starting_tab_count = browser()->tab_strip_model()->count();
227  AddSomeTabs(browser(), 3);
228
229  // Close one in the middle
230  int closed_tab_index = starting_tab_count + 1;
231  CloseTab(closed_tab_index);
232  EXPECT_EQ(starting_tab_count + 2, browser()->tab_strip_model()->count());
233
234  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, closed_tab_index));
235
236  // And make sure everything looks right.
237  EXPECT_EQ(starting_tab_count + 3, browser()->tab_strip_model()->count());
238  EXPECT_EQ(closed_tab_index, browser()->tab_strip_model()->active_index());
239  EXPECT_EQ(url1_,
240            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
241}
242
243// Close a tab, switch windows, then restore the tab. The tab should be in its
244// original window and position, and active.
245IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreToDifferentWindow) {
246  int starting_tab_count = browser()->tab_strip_model()->count();
247  AddSomeTabs(browser(), 3);
248
249  // Close one in the middle
250  int closed_tab_index = starting_tab_count + 1;
251  CloseTab(closed_tab_index);
252  EXPECT_EQ(starting_tab_count + 2, browser()->tab_strip_model()->count());
253
254  // Create a new browser.
255  ui_test_utils::NavigateToURLWithDisposition(
256      browser(), GURL(chrome::kChromeUINewTabURL), NEW_WINDOW,
257      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
258  EXPECT_EQ(2u, active_browser_list_->size());
259
260  // Restore tab into original browser.
261  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, closed_tab_index));
262
263  // And make sure everything looks right.
264  EXPECT_EQ(starting_tab_count + 3, browser()->tab_strip_model()->count());
265  EXPECT_EQ(closed_tab_index, browser()->tab_strip_model()->active_index());
266  EXPECT_EQ(url1_,
267            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
268}
269
270// Close a tab, open a new window, close the first window, then restore the
271// tab. It should be in a new window.
272// If this becomes flaky, use http://crbug.com/14774
273IN_PROC_BROWSER_TEST_F(TabRestoreTest, DISABLED_BasicRestoreFromClosedWindow) {
274  // Navigate to url1 then url2.
275  ui_test_utils::NavigateToURL(browser(), url1_);
276  ui_test_utils::NavigateToURL(browser(), url2_);
277
278  // Create a new browser.
279  ui_test_utils::NavigateToURLWithDisposition(
280      browser(), GURL(chrome::kChromeUINewTabURL), NEW_WINDOW,
281      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
282  EXPECT_EQ(2u, active_browser_list_->size());
283
284  // Close the final tab in the first browser.
285  content::WindowedNotificationObserver window_observer(
286      chrome::NOTIFICATION_BROWSER_CLOSED,
287      content::NotificationService::AllSources());
288  CloseTab(0);
289  window_observer.Wait();
290
291  ASSERT_NO_FATAL_FAILURE(RestoreTab(1, 0));
292
293  // Tab should be in a new window.
294  Browser* browser = GetBrowser(1);
295  content::WebContents* web_contents =
296      browser->tab_strip_model()->GetActiveWebContents();
297  // And make sure the URLs match.
298  EXPECT_EQ(url2_, web_contents->GetURL());
299  GoBack(browser);
300  EXPECT_EQ(url1_, web_contents->GetURL());
301}
302
303#if defined(OS_WIN)
304// Flakily times out: http://crbug.com/171503
305#define MAYBE_DontLoadRestoredTab DISABLED_DontLoadRestoredTab
306#else
307#define MAYBE_DontLoadRestoredTab DontLoadRestoredTab
308#endif
309
310// Restore a tab then make sure it doesn't restore again.
311IN_PROC_BROWSER_TEST_F(TabRestoreTest, MAYBE_DontLoadRestoredTab) {
312  // Add two tabs
313  int starting_tab_count = browser()->tab_strip_model()->count();
314  AddSomeTabs(browser(), 2);
315  ASSERT_EQ(browser()->tab_strip_model()->count(), starting_tab_count + 2);
316
317  // Close one of them.
318  CloseTab(0);
319  ASSERT_EQ(browser()->tab_strip_model()->count(), starting_tab_count + 1);
320
321  // Restore it.
322  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 0));
323  ASSERT_EQ(browser()->tab_strip_model()->count(), starting_tab_count + 2);
324
325  // Make sure that there's nothing else to restore.
326  ASSERT_EQ(chrome::GetRestoreTabType(browser()),
327            TabStripModelDelegate::RESTORE_NONE);
328}
329
330// Open a window with multiple tabs, close a tab, then close the window.
331// Restore both and make sure the tab goes back into the window.
332IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreWindowAndTab) {
333  int starting_tab_count = browser()->tab_strip_model()->count();
334  AddSomeTabs(browser(), 3);
335
336  // Close one in the middle
337  int closed_tab_index = starting_tab_count + 1;
338  CloseTab(closed_tab_index);
339  EXPECT_EQ(starting_tab_count + 2, browser()->tab_strip_model()->count());
340
341  // Create a new browser.
342  ui_test_utils::NavigateToURLWithDisposition(
343      browser(), GURL(chrome::kChromeUINewTabURL), NEW_WINDOW,
344      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
345  EXPECT_EQ(2u, active_browser_list_->size());
346
347  // Close the first browser.
348  content::WindowedNotificationObserver observer(
349      chrome::NOTIFICATION_BROWSER_CLOSED,
350      content::NotificationService::AllSources());
351  chrome::CloseWindow(browser());
352  observer.Wait();
353  EXPECT_EQ(1u, active_browser_list_->size());
354
355  // Restore the first window. The expected_tabstrip_index (second argument)
356  // indicates the expected active tab.
357  ASSERT_NO_FATAL_FAILURE(RestoreTab(1, starting_tab_count + 1));
358  Browser* browser = GetBrowser(1);
359  EXPECT_EQ(starting_tab_count + 2, browser->tab_strip_model()->count());
360
361  // Restore the closed tab.
362  ASSERT_NO_FATAL_FAILURE(RestoreTab(1, closed_tab_index));
363  EXPECT_EQ(starting_tab_count + 3, browser->tab_strip_model()->count());
364  EXPECT_EQ(url1_,
365            browser->tab_strip_model()->GetActiveWebContents()->GetURL());
366}
367
368// Open a window with two tabs, close both (closing the window), then restore
369// both. Make sure both restored tabs are in the same window.
370IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreIntoSameWindow) {
371  ui_test_utils::NavigateToURLWithDisposition(
372      browser(), url1_, NEW_FOREGROUND_TAB,
373      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
374  // Navigate the rightmost one to url2_ for easier identification.
375  ui_test_utils::NavigateToURLWithDisposition(
376      browser(), url2_, NEW_FOREGROUND_TAB,
377      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
378
379  // Create a new browser.
380  ui_test_utils::NavigateToURLWithDisposition(
381      browser(), GURL(chrome::kChromeUINewTabURL), NEW_WINDOW,
382      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
383  EXPECT_EQ(2u, active_browser_list_->size());
384
385  // Close all but one tab in the first browser, left to right.
386  while (browser()->tab_strip_model()->count() > 1)
387    CloseTab(0);
388
389  // Close the last tab, closing the browser.
390  content::WindowedNotificationObserver observer(
391      chrome::NOTIFICATION_BROWSER_CLOSED,
392      content::NotificationService::AllSources());
393  CloseTab(0);
394  observer.Wait();
395  EXPECT_EQ(1u, active_browser_list_->size());
396
397  // Restore the last-closed tab into a new window.
398  ASSERT_NO_FATAL_FAILURE(RestoreTab(1, 0));
399  Browser* browser = GetBrowser(1);
400  EXPECT_EQ(1, browser->tab_strip_model()->count());
401  EXPECT_EQ(url2_,
402            browser->tab_strip_model()->GetActiveWebContents()->GetURL());
403
404  // Restore the next-to-last-closed tab into the same window.
405  ASSERT_NO_FATAL_FAILURE(RestoreTab(1, 0));
406  EXPECT_EQ(2, browser->tab_strip_model()->count());
407  EXPECT_EQ(url1_,
408            browser->tab_strip_model()->GetActiveWebContents()->GetURL());
409}
410
411// Tests that a duplicate history entry is not created when we restore a page
412// to an existing SiteInstance.  (Bug 1230446)
413IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreWithExistingSiteInstance) {
414  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
415
416  GURL http_url1(embedded_test_server()->GetURL("/title1.html"));
417  GURL http_url2(embedded_test_server()->GetURL("/title2.html"));
418  int tab_count = browser()->tab_strip_model()->count();
419
420  // Add a tab
421  ui_test_utils::NavigateToURLWithDisposition(
422      browser(), http_url1, NEW_FOREGROUND_TAB,
423      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
424  EXPECT_EQ(++tab_count, browser()->tab_strip_model()->count());
425
426  // Navigate to another same-site URL.
427  content::WebContents* tab =
428      browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
429  content::WindowedNotificationObserver observer(
430      content::NOTIFICATION_LOAD_STOP,
431      content::NotificationService::AllSources());
432  static_cast<content::WebContentsDelegate*>(browser())->OpenURLFromTab(
433      tab,
434      content::OpenURLParams(http_url2, content::Referrer(), CURRENT_TAB,
435                             ui::PAGE_TRANSITION_TYPED, false));
436  observer.Wait();
437
438  // Close the tab.
439  CloseTab(1);
440
441  // Create a new tab to the original site.  Assuming process-per-site is
442  // enabled, this will ensure that the SiteInstance used by the restored tab
443  // will already exist when the restore happens.
444  ui_test_utils::NavigateToURLWithDisposition(
445      browser(), http_url2, NEW_FOREGROUND_TAB,
446      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
447
448  // Restore the closed tab.
449  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, tab_count - 1));
450
451  // And make sure the URLs match.
452  EXPECT_EQ(http_url2,
453            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
454  GoBack(browser());
455  EXPECT_EQ(http_url1,
456            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
457}
458
459// See crbug.com/248574
460#if defined(OS_WIN)
461#define MAYBE_RestoreCrossSiteWithExistingSiteInstance DISABLED_RestoreCrossSiteWithExistingSiteInstance
462#else
463#define MAYBE_RestoreCrossSiteWithExistingSiteInstance RestoreCrossSiteWithExistingSiteInstance
464#endif
465
466// Tests that the SiteInstances used for entries in a restored tab's history
467// are given appropriate max page IDs, even if the renderer for the entry
468// already exists.  (Bug 1204135)
469IN_PROC_BROWSER_TEST_F(TabRestoreTest,
470                       MAYBE_RestoreCrossSiteWithExistingSiteInstance) {
471  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
472
473  GURL http_url1(embedded_test_server()->GetURL("/title1.html"));
474  GURL http_url2(embedded_test_server()->GetURL("/title2.html"));
475
476  int tab_count = browser()->tab_strip_model()->count();
477
478  // Add a tab
479  ui_test_utils::NavigateToURLWithDisposition(
480      browser(), http_url1, NEW_FOREGROUND_TAB,
481      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
482  EXPECT_EQ(++tab_count, browser()->tab_strip_model()->count());
483
484  // Navigate to more URLs, then a cross-site URL.
485  ui_test_utils::NavigateToURLWithDisposition(
486      browser(), http_url2, CURRENT_TAB,
487      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
488  ui_test_utils::NavigateToURLWithDisposition(
489      browser(), http_url1, CURRENT_TAB,
490      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
491  ui_test_utils::NavigateToURLWithDisposition(
492      browser(), url1_, CURRENT_TAB,
493      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
494
495  // Close the tab.
496  CloseTab(1);
497
498  // Create a new tab to the original site.  Assuming process-per-site is
499  // enabled, this will ensure that the SiteInstance will already exist when
500  // the user clicks Back in the restored tab.
501  ui_test_utils::NavigateToURLWithDisposition(
502      browser(), http_url2, NEW_FOREGROUND_TAB,
503      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
504
505  // Restore the closed tab.
506  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, tab_count - 1));
507
508  // And make sure the URLs match.
509  EXPECT_EQ(url1_,
510            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
511  GoBack(browser());
512  EXPECT_EQ(http_url1,
513            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
514
515  // Navigating to a new URL should clear the forward list, because the max
516  // page ID of the renderer should have been updated when we restored the tab.
517  ui_test_utils::NavigateToURLWithDisposition(
518      browser(), http_url2, CURRENT_TAB,
519      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
520  EXPECT_FALSE(chrome::CanGoForward(browser()));
521  EXPECT_EQ(http_url2,
522            browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
523}
524
525IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreWindow) {
526  // Create a new window.
527  size_t window_count = active_browser_list_->size();
528  ui_test_utils::NavigateToURLWithDisposition(
529      browser(), GURL(chrome::kChromeUINewTabURL), NEW_WINDOW,
530      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
531  EXPECT_EQ(++window_count, active_browser_list_->size());
532
533  // Create two more tabs, one with url1, the other url2.
534  int initial_tab_count = browser()->tab_strip_model()->count();
535  ui_test_utils::NavigateToURLWithDisposition(
536      browser(), url1_, NEW_FOREGROUND_TAB,
537      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
538  ui_test_utils::NavigateToURLWithDisposition(
539      browser(), url2_, NEW_FOREGROUND_TAB,
540      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
541
542  // Close the window.
543  content::WindowedNotificationObserver close_window_observer(
544      chrome::NOTIFICATION_BROWSER_CLOSED,
545      content::NotificationService::AllSources());
546  chrome::CloseWindow(browser());
547  close_window_observer.Wait();
548  EXPECT_EQ(window_count - 1, active_browser_list_->size());
549
550  // Restore the window.
551  content::WindowedNotificationObserver open_window_observer(
552      chrome::NOTIFICATION_BROWSER_OPENED,
553      content::NotificationService::AllSources());
554  content::WindowedNotificationObserver load_stop_observer(
555      content::NOTIFICATION_LOAD_STOP,
556      content::NotificationService::AllSources());
557  chrome::RestoreTab(active_browser_list_->get(0));
558  open_window_observer.Wait();
559  EXPECT_EQ(window_count, active_browser_list_->size());
560
561  Browser* browser = GetBrowser(1);
562  EXPECT_EQ(initial_tab_count + 2, browser->tab_strip_model()->count());
563  load_stop_observer.Wait();
564
565  content::WebContents* restored_tab =
566      browser->tab_strip_model()->GetWebContentsAt(initial_tab_count);
567  EnsureTabFinishedRestoring(restored_tab);
568  EXPECT_EQ(url1_, restored_tab->GetURL());
569
570  restored_tab =
571      browser->tab_strip_model()->GetWebContentsAt(initial_tab_count + 1);
572  EnsureTabFinishedRestoring(restored_tab);
573  EXPECT_EQ(url2_, restored_tab->GetURL());
574}
575
576// Restore tab with special URL chrome://credits/ and make sure the page loads
577// properly after restore. See http://crbug.com/31905.
578IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreTabWithSpecialURL) {
579  // Navigate new tab to a special URL.
580  ui_test_utils::NavigateToURLWithDisposition(
581      browser(), GURL(chrome::kChromeUICreditsURL), NEW_FOREGROUND_TAB,
582      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
583
584  // Close the tab.
585  CloseTab(1);
586
587  // Restore the closed tab.
588  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 1));
589  content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
590  EnsureTabFinishedRestoring(tab);
591
592  // See if content is as expected.
593  EXPECT_GT(
594      ui_test_utils::FindInPage(tab, base::ASCIIToUTF16("webkit"), true, false,
595                                NULL, NULL),
596      0);
597}
598
599// Restore tab with special URL in its navigation history, go back to that
600// entry and see that it loads properly. See http://crbug.com/31905
601IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreTabWithSpecialURLOnBack) {
602  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
603
604  const GURL http_url(embedded_test_server()->GetURL("/title1.html"));
605
606  // Navigate new tab to a special URL.
607  ui_test_utils::NavigateToURLWithDisposition(
608      browser(), GURL(chrome::kChromeUICreditsURL), NEW_FOREGROUND_TAB,
609      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
610
611  // Then navigate to a normal URL.
612  ui_test_utils::NavigateToURL(browser(), http_url);
613
614  // Close the tab.
615  CloseTab(1);
616
617  // Restore the closed tab.
618  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 1));
619  content::WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
620  EnsureTabFinishedRestoring(tab);
621  ASSERT_EQ(http_url, tab->GetURL());
622
623  // Go back, and see if content is as expected.
624  GoBack(browser());
625  EXPECT_GT(
626      ui_test_utils::FindInPage(tab, base::ASCIIToUTF16("webkit"), true, false,
627                                NULL, NULL),
628      0);
629}
630
631IN_PROC_BROWSER_TEST_F(TabRestoreTest, PRE_RestoreOnStartup) {
632  // This results in a new tab at the end with url1.
633  AddSomeTabs(browser(), 1);
634
635  while (browser()->tab_strip_model()->count())
636    CloseTab(0);
637}
638
639// Verifies restoring a tab works on startup.
640IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoreOnStartup) {
641  ASSERT_NO_FATAL_FAILURE(RestoreTab(0, 1));
642  EXPECT_EQ(url1_,
643            browser()->tab_strip_model()->GetWebContentsAt(1)->GetURL());
644}
645