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