1// Copyright (c) 2011 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/file_path.h"
8#include "base/test/test_timeouts.h"
9#include "chrome/app/chrome_command_ids.h"
10#include "chrome/common/chrome_paths.h"
11#include "chrome/common/url_constants.h"
12#include "chrome/test/automation/tab_proxy.h"
13#include "chrome/test/automation/browser_proxy.h"
14#include "chrome/test/automation/window_proxy.h"
15#include "chrome/test/ui/ui_test.h"
16#include "googleurl/src/gurl.h"
17#include "net/base/net_util.h"
18#include "net/test/test_server.h"
19
20// http://code.google.com/p/chromium/issues/detail?id=14774
21#if (defined(OS_WIN) || defined(OS_CHROMEOS)) && !defined(NDEBUG)
22#define MAYBE_BasicRestoreFromClosedWindow DISABLED_BasicRestoreFromClosedWindow
23#else
24#define MAYBE_BasicRestoreFromClosedWindow BasicRestoreFromClosedWindow
25#endif
26
27class TabRestoreUITest : public UITest {
28 public:
29  TabRestoreUITest() : UITest() {
30    FilePath path_prefix(test_data_directory_);
31    path_prefix = path_prefix.AppendASCII("session_history");
32    url1_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot1.html"));
33    url2_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot2.html"));
34  }
35
36 protected:
37  // Uses the undo-close-tab accelerator to undo a close-tab or close-window
38  // operation. The newly restored tab is expected to appear in the
39  // window at index |expected_window_index|, at the |expected_tabstrip_index|,
40  // and to be active. If |expected_window_index| is equal to the number of
41  // current windows, the restored tab is expected to be created in a new
42  // window (since the index is 0-based).
43  void RestoreTab(int expected_window_index,
44                  int expected_tabstrip_index) {
45    int tab_count = 0;
46    int window_count = 0;
47
48    ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
49    ASSERT_GT(window_count, 0);
50
51    bool expect_new_window = (expected_window_index == window_count);
52    scoped_refptr<BrowserProxy> browser_proxy;
53    if (expect_new_window) {
54      browser_proxy = automation()->GetBrowserWindow(0);
55    } else {
56      ASSERT_GT(window_count, expected_window_index);
57      browser_proxy = automation()->GetBrowserWindow(expected_window_index);
58    }
59    ASSERT_TRUE(browser_proxy.get());
60    ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
61    ASSERT_GT(tab_count, 0);
62
63    // Restore the tab.
64    ASSERT_TRUE(browser_proxy->RunCommand(IDC_RESTORE_TAB));
65
66    if (expect_new_window) {
67      int new_window_count = 0;
68      ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count));
69      EXPECT_EQ(++window_count, new_window_count);
70      browser_proxy = automation()->GetBrowserWindow(expected_window_index);
71      ASSERT_TRUE(browser_proxy.get());
72    } else {
73      int new_tab_count = 0;
74      ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count));
75      EXPECT_EQ(++tab_count, new_tab_count);
76    }
77
78    // Get a handle to the restored tab.
79    ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
80    ASSERT_GT(tab_count, expected_tabstrip_index);
81    scoped_refptr<TabProxy> restored_tab_proxy(
82        browser_proxy->GetTab(expected_tabstrip_index));
83    ASSERT_TRUE(restored_tab_proxy.get());
84    // Wait for the restored tab to finish loading.
85    ASSERT_TRUE(restored_tab_proxy->WaitForTabToBeRestored(
86        TestTimeouts::action_max_timeout_ms()));
87
88    // Ensure that the tab and window are active.
89    CheckActiveWindow(browser_proxy.get());
90    EXPECT_EQ(expected_tabstrip_index,
91        GetActiveTabIndex(expected_window_index));
92  }
93
94  // Adds tabs to the given browser, all navigated to url1_. Returns
95  // the final number of tabs.
96  int AddSomeTabs(BrowserProxy* browser, int how_many) {
97    int starting_tab_count = -1;
98    EXPECT_TRUE(browser->GetTabCount(&starting_tab_count));
99
100    for (int i = 0; i < how_many; ++i) {
101      EXPECT_TRUE(browser->AppendTab(url1_));
102    }
103    int tab_count;
104    EXPECT_TRUE(browser->GetTabCount(&tab_count));
105    EXPECT_EQ(starting_tab_count + how_many, tab_count);
106    return tab_count;
107  }
108
109  // Ensure that the given browser occupies the currently active window.
110  void CheckActiveWindow(const BrowserProxy* browser) {
111    // This entire check is disabled because even the IsActive() call
112    // sporadically fails to complete successfully. See http://crbug.com/10916.
113    // TODO(pamg): Investigate and re-enable. Also find a way to have the
114    // calling location reported in the gtest error, by inlining this again if
115    // nothing else.
116    return;
117
118    bool is_active = false;
119    scoped_refptr<WindowProxy> window_proxy(browser->GetWindow());
120    ASSERT_TRUE(window_proxy.get());
121    ASSERT_TRUE(window_proxy->IsActive(&is_active));
122    // The check for is_active may fail if other apps are active while running
123    // the tests, because Chromium won't be the foremost application at all.
124    // So we'll have it log an error, but not report one through gtest, to
125    // keep the test result deterministic and the buildbots happy.
126    if (!is_active)
127      LOG(ERROR) << "WARNING: is_active was false, expected true. (This may "
128                    "be simply because Chromium isn't the front application.)";
129  }
130
131  GURL url1_;
132  GURL url2_;
133
134 private:
135  DISALLOW_COPY_AND_ASSIGN(TabRestoreUITest);
136};
137
138// Close the end tab in the current window, then restore it. The tab should be
139// in its original position, and active.
140TEST_F(TabRestoreUITest, Basic) {
141  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
142  ASSERT_TRUE(browser_proxy.get());
143
144  int starting_tab_count;
145  ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count));
146  int tab_count = AddSomeTabs(browser_proxy.get(), 1);
147
148  int closed_tab_index = tab_count - 1;
149  scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index));
150  ASSERT_TRUE(new_tab.get());
151  // Make sure we're at url.
152  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_));
153  // Close the tab.
154  ASSERT_TRUE(new_tab->Close(true));
155  new_tab = NULL;
156  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
157  EXPECT_EQ(starting_tab_count, tab_count);
158
159  RestoreTab(0, closed_tab_index);
160
161  // And make sure everything looks right.
162  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
163  EXPECT_EQ(starting_tab_count + 1, tab_count);
164  EXPECT_EQ(closed_tab_index, GetActiveTabIndex());
165  EXPECT_EQ(url1_, GetActiveTabURL());
166}
167
168// Close a tab not at the end of the current window, then restore it. The tab
169// should be in its original position, and active.
170TEST_F(TabRestoreUITest, MiddleTab) {
171  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
172  ASSERT_TRUE(browser_proxy.get());
173
174  int starting_tab_count;
175  ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count));
176  int tab_count = AddSomeTabs(browser_proxy.get(), 3);
177
178  // Close one in the middle
179  int closed_tab_index = starting_tab_count + 1;
180  scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index));
181  ASSERT_TRUE(new_tab.get());
182  // Make sure we're at url.
183  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_));
184  // Close the tab.
185  ASSERT_TRUE(new_tab->Close(true));
186  new_tab = NULL;
187  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
188  EXPECT_EQ(starting_tab_count + 2, tab_count);
189
190  RestoreTab(0, closed_tab_index);
191
192  // And make sure everything looks right.
193  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
194  EXPECT_EQ(starting_tab_count + 3, tab_count);
195  EXPECT_EQ(closed_tab_index, GetActiveTabIndex());
196  EXPECT_EQ(url1_, GetActiveTabURL());
197}
198
199// Close a tab, switch windows, then restore the tab. The tab should be in its
200// original window and position, and active.
201TEST_F(TabRestoreUITest, RestoreToDifferentWindow) {
202  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
203  ASSERT_TRUE(browser_proxy.get());
204
205  // This call is virtually guaranteed to pass, assuming that Chromium is the
206  // active application, which will establish a baseline for later calls to
207  // CheckActiveWindow(). See comments in that function.
208  CheckActiveWindow(browser_proxy.get());
209
210  int starting_tab_count;
211  ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count));
212  int tab_count = AddSomeTabs(browser_proxy.get(), 3);
213
214  // Close one in the middle
215  int closed_tab_index = starting_tab_count + 1;
216  scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index));
217  ASSERT_TRUE(new_tab.get());
218  // Make sure we're at url.
219  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_));
220  // Close the tab.
221  ASSERT_TRUE(new_tab->Close(true));
222  new_tab = NULL;
223  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
224  EXPECT_EQ(starting_tab_count + 2, tab_count);
225
226  // Create a new browser.
227  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false));
228  int window_count;
229  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
230  EXPECT_EQ(2, window_count);
231
232  CheckActiveWindow(automation()->GetBrowserWindow(1));
233
234  // Restore tab into original browser.
235  RestoreTab(0, closed_tab_index);
236
237  // And make sure everything looks right.
238  CheckActiveWindow(browser_proxy.get());
239  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
240  EXPECT_EQ(starting_tab_count + 3, tab_count);
241  EXPECT_EQ(closed_tab_index, GetActiveTabIndex(0));
242  EXPECT_EQ(url1_, GetActiveTabURL(0));
243}
244
245// Close a tab, open a new window, close the first window, then restore the
246// tab. It should be in a new window.
247TEST_F(TabRestoreUITest, MAYBE_BasicRestoreFromClosedWindow) {
248  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
249  ASSERT_TRUE(browser_proxy.get());
250  CheckActiveWindow(browser_proxy.get());
251
252  int tab_count;
253  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
254
255  // Close tabs until we only have one open.
256  while (tab_count > 1) {
257    scoped_refptr<TabProxy> tab_to_close(browser_proxy->GetTab(0));
258    ASSERT_TRUE(tab_to_close.get());
259    ASSERT_TRUE(tab_to_close->Close(true));
260    ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
261  }
262
263  // Navigate to url1 then url2.
264  scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
265  ASSERT_TRUE(tab_proxy.get());
266  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->NavigateToURL(url1_));
267  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->NavigateToURL(url2_));
268
269  // Create a new browser.
270  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false));
271  int window_count;
272  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
273  EXPECT_EQ(2, window_count);
274  CheckActiveWindow(automation()->GetBrowserWindow(1));
275
276  // Close the final tab in the first browser.
277  EXPECT_TRUE(tab_proxy->Close(true));
278  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(1));
279
280  // Tab and browser are no longer valid.
281  tab_proxy = NULL;
282  browser_proxy = NULL;
283
284  RestoreTab(1, 0);
285
286  // Tab should be in a new window.
287  browser_proxy = automation()->GetBrowserWindow(1);
288  ASSERT_TRUE(browser_proxy.get());
289  CheckActiveWindow(browser_proxy.get());
290  tab_proxy = browser_proxy->GetActiveTab();
291  ASSERT_TRUE(tab_proxy.get());
292  // And make sure the URLs matches.
293  EXPECT_EQ(url2_, GetActiveTabURL(1));
294  EXPECT_TRUE(tab_proxy->GoBack());
295  EXPECT_EQ(url1_, GetActiveTabURL(1));
296}
297
298// Restore a tab then make sure it doesn't restore again.
299TEST_F(TabRestoreUITest, DontLoadRestoredTab) {
300  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
301  ASSERT_TRUE(browser_proxy.get());
302  CheckActiveWindow(browser_proxy.get());
303
304  // Add two tabs
305  int starting_tab_count = 0;
306  ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count));
307  AddSomeTabs(browser_proxy.get(), 2);
308  int current_tab_count = 0;
309  ASSERT_TRUE(browser_proxy->GetTabCount(&current_tab_count));
310  ASSERT_EQ(current_tab_count, starting_tab_count + 2);
311
312  // Close one of them.
313  scoped_refptr<TabProxy> tab_to_close(browser_proxy->GetTab(0));
314  ASSERT_TRUE(tab_to_close.get());
315  ASSERT_TRUE(tab_to_close->Close(true));
316  ASSERT_TRUE(browser_proxy->GetTabCount(&current_tab_count));
317  ASSERT_EQ(current_tab_count, starting_tab_count + 1);
318
319  // Restore it.
320  RestoreTab(0, 0);
321  ASSERT_TRUE(browser_proxy->GetTabCount(&current_tab_count));
322  ASSERT_EQ(current_tab_count, starting_tab_count + 2);
323
324  // Make sure that there's nothing else to restore.
325  bool enabled;
326  ASSERT_TRUE(browser_proxy->IsMenuCommandEnabled(IDC_RESTORE_TAB, &enabled));
327  EXPECT_FALSE(enabled);
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.
332TEST_F(TabRestoreUITest, RestoreWindowAndTab) {
333  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
334  ASSERT_TRUE(browser_proxy.get());
335  CheckActiveWindow(browser_proxy.get());
336
337  int starting_tab_count;
338  ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count));
339  int tab_count = AddSomeTabs(browser_proxy.get(), 3);
340
341  // Close one in the middle
342  int closed_tab_index = starting_tab_count + 1;
343  scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(closed_tab_index));
344  ASSERT_TRUE(new_tab.get());
345  // Make sure we're at url.
346  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_));
347  // Close the tab.
348  ASSERT_TRUE(new_tab->Close(true));
349  new_tab = NULL;
350  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
351  EXPECT_EQ(starting_tab_count + 2, tab_count);
352
353  // Create a new browser.
354  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false));
355  int window_count;
356  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
357  EXPECT_EQ(2, window_count);
358  CheckActiveWindow(automation()->GetBrowserWindow(1));
359
360  // Close the first browser.
361  bool application_closing;
362  EXPECT_TRUE(CloseBrowser(browser_proxy.get(), &application_closing));
363  EXPECT_FALSE(application_closing);
364  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
365  EXPECT_EQ(1, window_count);
366
367  // Browser is no longer valid.
368  browser_proxy = NULL;
369
370  // Restore the first window. The expected_tabstrip_index (second argument)
371  // indicates the expected active tab.
372  RestoreTab(1, starting_tab_count + 1);
373  browser_proxy = automation()->GetBrowserWindow(1);
374  ASSERT_TRUE(browser_proxy.get());
375  CheckActiveWindow(browser_proxy.get());
376  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
377  EXPECT_EQ(starting_tab_count + 2, tab_count);
378
379  // Restore the closed tab.
380  RestoreTab(1, closed_tab_index);
381  CheckActiveWindow(browser_proxy.get());
382  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
383  EXPECT_EQ(starting_tab_count + 3, tab_count);
384  EXPECT_EQ(url1_, GetActiveTabURL(1));
385}
386
387// Open a window with two tabs, close both (closing the window), then restore
388// both. Make sure both restored tabs are in the same window.
389TEST_F(TabRestoreUITest, RestoreIntoSameWindow) {
390  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
391  ASSERT_TRUE(browser_proxy.get());
392  CheckActiveWindow(browser_proxy.get());
393
394  int starting_tab_count;
395  ASSERT_TRUE(browser_proxy->GetTabCount(&starting_tab_count));
396  int tab_count = AddSomeTabs(browser_proxy.get(), 2);
397
398  // Navigate the rightmost one to url2_ for easier identification.
399  scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(tab_count - 1));
400  ASSERT_TRUE(tab_proxy.get());
401  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->NavigateToURL(url2_));
402
403  // Create a new browser.
404  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false));
405  int window_count;
406  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
407  EXPECT_EQ(2, window_count);
408  CheckActiveWindow(automation()->GetBrowserWindow(1));
409
410  // Close all but one tab in the first browser, left to right.
411  while (tab_count > 1) {
412    scoped_refptr<TabProxy> tab_to_close(browser_proxy->GetTab(0));
413    ASSERT_TRUE(tab_to_close.get());
414    ASSERT_TRUE(tab_to_close->Close(true));
415    ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
416  }
417
418  // Close the last tab, closing the browser.
419  tab_proxy = browser_proxy->GetTab(0);
420  ASSERT_TRUE(tab_proxy.get());
421  EXPECT_TRUE(tab_proxy->Close(true));
422  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(1));
423  browser_proxy = NULL;
424  tab_proxy = NULL;
425
426  // Restore the last-closed tab into a new window.
427  RestoreTab(1, 0);
428  browser_proxy = automation()->GetBrowserWindow(1);
429  ASSERT_TRUE(browser_proxy.get());
430  CheckActiveWindow(browser_proxy.get());
431  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
432  EXPECT_EQ(1, tab_count);
433  EXPECT_EQ(url2_, GetActiveTabURL(1));
434
435  // Restore the next-to-last-closed tab into the same window.
436  RestoreTab(1, 0);
437  CheckActiveWindow(browser_proxy.get());
438  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
439  EXPECT_EQ(2, tab_count);
440  EXPECT_EQ(url1_, GetActiveTabURL(1));
441}
442
443// Tests that a duplicate history entry is not created when we restore a page
444// to an existing SiteInstance.  (Bug 1230446)
445TEST_F(TabRestoreUITest, RestoreWithExistingSiteInstance) {
446  net::TestServer test_server(net::TestServer::TYPE_HTTP,
447                              FilePath(FILE_PATH_LITERAL("chrome/test/data")));
448  ASSERT_TRUE(test_server.Start());
449
450  GURL http_url1(test_server.GetURL("files/title1.html"));
451  GURL http_url2(test_server.GetURL("files/title2.html"));
452
453  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
454  ASSERT_TRUE(browser_proxy.get());
455  int tab_count;
456  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
457
458  // Add a tab
459  ASSERT_TRUE(browser_proxy->AppendTab(http_url1));
460  int new_tab_count;
461  ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count));
462  EXPECT_EQ(++tab_count, new_tab_count);
463  scoped_refptr<TabProxy> tab(browser_proxy->GetTab(tab_count - 1));
464  ASSERT_TRUE(tab.get());
465
466  // Navigate to another same-site URL.
467  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url2));
468
469  // Close the tab.
470  ASSERT_TRUE(tab->Close(true));
471  tab = NULL;
472
473  // Create a new tab to the original site.  Assuming process-per-site is
474  // enabled, this will ensure that the SiteInstance used by the restored tab
475  // will already exist when the restore happens.
476  ASSERT_TRUE(browser_proxy->AppendTab(http_url2));
477
478  // Restore the closed tab.
479  RestoreTab(0, tab_count - 1);
480  tab = browser_proxy->GetActiveTab();
481  ASSERT_TRUE(tab.get());
482
483  // And make sure the URLs match.
484  EXPECT_EQ(http_url2, GetActiveTabURL());
485  EXPECT_TRUE(tab->GoBack());
486  EXPECT_EQ(http_url1, GetActiveTabURL());
487}
488
489// Tests that the SiteInstances used for entries in a restored tab's history
490// are given appropriate max page IDs, even if the renderer for the entry
491// already exists.  (Bug 1204135)
492TEST_F(TabRestoreUITest, RestoreCrossSiteWithExistingSiteInstance) {
493  net::TestServer test_server(net::TestServer::TYPE_HTTP,
494                              FilePath(FILE_PATH_LITERAL("chrome/test/data")));
495  ASSERT_TRUE(test_server.Start());
496
497  GURL http_url1(test_server.GetURL("files/title1.html"));
498  GURL http_url2(test_server.GetURL("files/title2.html"));
499
500  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
501  ASSERT_TRUE(browser_proxy.get());
502  int tab_count;
503  ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
504
505  // Add a tab
506  ASSERT_TRUE(browser_proxy->AppendTab(http_url1));
507  int new_tab_count;
508  ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count));
509  EXPECT_EQ(++tab_count, new_tab_count);
510  scoped_refptr<TabProxy> tab(browser_proxy->GetTab(tab_count - 1));
511  ASSERT_TRUE(tab.get());
512
513  // Navigate to more URLs, then a cross-site URL.
514  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url2));
515  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url1));
516  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(url1_));
517
518  // Close the tab.
519  ASSERT_TRUE(tab->Close(true));
520  tab = NULL;
521
522  // Create a new tab to the original site.  Assuming process-per-site is
523  // enabled, this will ensure that the SiteInstance will already exist when
524  // the user clicks Back in the restored tab.
525  ASSERT_TRUE(browser_proxy->AppendTab(http_url2));
526
527  // Restore the closed tab.
528  RestoreTab(0, tab_count - 1);
529  tab = browser_proxy->GetActiveTab();
530  ASSERT_TRUE(tab.get());
531
532  // And make sure the URLs match.
533  EXPECT_EQ(url1_, GetActiveTabURL());
534  EXPECT_TRUE(tab->GoBack());
535  EXPECT_EQ(http_url1, GetActiveTabURL());
536
537  // Navigating to a new URL should clear the forward list, because the max
538  // page ID of the renderer should have been updated when we restored the tab.
539  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(http_url2));
540  EXPECT_FALSE(tab->GoForward());
541  EXPECT_EQ(http_url2, GetActiveTabURL());
542}
543
544TEST_F(TabRestoreUITest, RestoreWindow) {
545  // Create a new window.
546  int window_count;
547  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
548  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, false));
549  int new_window_count = 0;
550  ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count));
551  EXPECT_EQ(++window_count, new_window_count);
552
553  // Create two more tabs, one with url1, the other url2.
554  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
555  ASSERT_TRUE(browser_proxy.get());
556  int initial_tab_count;
557  ASSERT_TRUE(browser_proxy->GetTabCount(&initial_tab_count));
558  ASSERT_TRUE(browser_proxy->AppendTab(url1_));
559  ASSERT_TRUE(browser_proxy->WaitForTabCountToBecome(initial_tab_count + 1));
560  scoped_refptr<TabProxy> new_tab(browser_proxy->GetTab(initial_tab_count));
561  ASSERT_TRUE(new_tab.get());
562  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url1_));
563  ASSERT_TRUE(browser_proxy->AppendTab(url2_));
564  ASSERT_TRUE(browser_proxy->WaitForTabCountToBecome(initial_tab_count + 2));
565  new_tab = browser_proxy->GetTab(initial_tab_count + 1);
566  ASSERT_TRUE(new_tab.get());
567  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, new_tab->NavigateToURL(url2_));
568
569  // Close the window.
570  ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW));
571  browser_proxy = NULL;
572  new_tab = NULL;
573  ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count));
574  EXPECT_EQ(window_count - 1, new_window_count);
575
576  // Restore the window.
577  browser_proxy = automation()->GetBrowserWindow(0);
578  ASSERT_TRUE(browser_proxy.get());
579  ASSERT_TRUE(browser_proxy->RunCommand(IDC_RESTORE_TAB));
580  ASSERT_TRUE(automation()->GetBrowserWindowCount(&new_window_count));
581  EXPECT_EQ(window_count, new_window_count);
582
583  browser_proxy = automation()->GetBrowserWindow(1);
584  int tab_count;
585  EXPECT_TRUE(browser_proxy->GetTabCount(&tab_count));
586  EXPECT_EQ(initial_tab_count + 2, tab_count);
587
588  scoped_refptr<TabProxy> restored_tab_proxy(
589        browser_proxy->GetTab(initial_tab_count));
590  ASSERT_TRUE(restored_tab_proxy.get());
591  ASSERT_TRUE(restored_tab_proxy->WaitForTabToBeRestored(
592      TestTimeouts::action_timeout_ms()));
593  GURL url;
594  ASSERT_TRUE(restored_tab_proxy->GetCurrentURL(&url));
595  EXPECT_TRUE(url == url1_);
596
597  restored_tab_proxy = browser_proxy->GetTab(initial_tab_count + 1);
598  ASSERT_TRUE(restored_tab_proxy.get());
599  ASSERT_TRUE(restored_tab_proxy->WaitForTabToBeRestored(
600      TestTimeouts::action_timeout_ms()));
601  ASSERT_TRUE(restored_tab_proxy->GetCurrentURL(&url));
602  EXPECT_TRUE(url == url2_);
603}
604
605// Restore tab with special URL about:credits and make sure the page loads
606// properly after restore. See http://crbug.com/31905.
607TEST_F(TabRestoreUITest, RestoreTabWithSpecialURL) {
608  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
609  ASSERT_TRUE(browser.get());
610  CheckActiveWindow(browser.get());
611
612  // Navigate new tab to a special URL.
613  const GURL special_url(chrome::kAboutCreditsURL);
614  ASSERT_TRUE(browser->AppendTab(special_url));
615  scoped_refptr<TabProxy> tab(browser->GetActiveTab());
616  ASSERT_TRUE(tab.get());
617
618  // Close the tab.
619  ASSERT_TRUE(tab->Close(true));
620
621  // Restore the closed tab.
622  RestoreTab(0, 1);
623  tab = browser->GetTab(1);
624  ASSERT_TRUE(tab.get());
625  ASSERT_TRUE(tab->WaitForTabToBeRestored(TestTimeouts::action_timeout_ms()));
626
627  // See if content is as expected.
628  EXPECT_TRUE(tab->FindInPage(std::wstring(L"webkit"), FWD, IGNORE_CASE, false,
629                              NULL));
630}
631
632// Restore tab with special URL in its navigation history, go back to that
633// entry and see that it loads properly. See http://crbug.com/31905
634TEST_F(TabRestoreUITest, RestoreTabWithSpecialURLOnBack) {
635  net::TestServer test_server(net::TestServer::TYPE_HTTP,
636                              FilePath(FILE_PATH_LITERAL("chrome/test/data")));
637  ASSERT_TRUE(test_server.Start());
638
639  const GURL http_url(test_server.GetURL("files/title1.html"));
640
641  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
642  ASSERT_TRUE(browser.get());
643  CheckActiveWindow(browser.get());
644
645  // Navigate new tab to a special URL.
646  const GURL special_url(chrome::kAboutCreditsURL);
647  ASSERT_TRUE(browser->AppendTab(special_url));
648  scoped_refptr<TabProxy> tab(browser->GetActiveTab());
649  ASSERT_TRUE(tab.get());
650
651  // Then navigate to a normal URL.
652  ASSERT_TRUE(tab->NavigateToURL(http_url));
653
654  // Close the tab.
655  ASSERT_TRUE(tab->Close(true));
656
657  // Restore the closed tab.
658  RestoreTab(0, 1);
659  tab = browser->GetTab(1);
660  ASSERT_TRUE(tab.get());
661  ASSERT_TRUE(tab->WaitForTabToBeRestored(TestTimeouts::action_timeout_ms()));
662  GURL url;
663  ASSERT_TRUE(tab->GetCurrentURL(&url));
664  ASSERT_EQ(http_url, url);
665
666  // Go back, and see if content is as expected.
667  ASSERT_TRUE(tab->GoBack());
668  EXPECT_TRUE(tab->FindInPage(std::wstring(L"webkit"), FWD, IGNORE_CASE, false,
669                              NULL));
670}
671