• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/command_line.h"
6 #include "base/file_path.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/string_number_conversions.h"
9 #include "base/test/test_timeouts.h"
10 #include "chrome/app/chrome_command_ids.h"
11 #include "chrome/browser/defaults.h"
12 #include "chrome/common/chrome_paths.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/test/automation/tab_proxy.h"
15 #include "chrome/test/automation/browser_proxy.h"
16 #include "chrome/test/automation/window_proxy.h"
17 #include "chrome/test/ui/ui_test.h"
18 #include "googleurl/src/gurl.h"
19 #include "net/base/net_util.h"
20 #include "net/test/test_server.h"
21 
22 namespace {
23 
24 class SessionRestoreUITest : public UITest {
25  protected:
SessionRestoreUITest()26   SessionRestoreUITest() : UITest() {
27     FilePath path_prefix = test_data_directory_.AppendASCII("session_history");
28 
29     url1_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot1.html"));
30     url2_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot2.html"));
31     url3_ = net::FilePathToFileURL(path_prefix.AppendASCII("bot3.html"));
32   }
33 
QuitBrowserAndRestore(int expected_tab_count)34   virtual void QuitBrowserAndRestore(int expected_tab_count) {
35 #if defined(OS_MACOSX)
36     set_shutdown_type(ProxyLauncher::USER_QUIT);
37 #endif
38     UITest::TearDown();
39 
40     clear_profile_ = false;
41 
42     launch_arguments_.AppendSwitchASCII(switches::kRestoreLastSession,
43                                         base::IntToString(expected_tab_count));
44     UITest::SetUp();
45   }
46 
CloseWindow(int window_index,int initial_count)47   void CloseWindow(int window_index, int initial_count) {
48     scoped_refptr<BrowserProxy> browser_proxy(
49         automation()->GetBrowserWindow(window_index));
50     ASSERT_TRUE(browser_proxy.get());
51     ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW));
52     int window_count;
53     ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
54     ASSERT_EQ(initial_count - 1, window_count);
55   }
56 
AssertOneWindowWithOneTab()57   void AssertOneWindowWithOneTab() {
58     int window_count;
59     ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
60     ASSERT_EQ(1, window_count);
61     GURL url;
62     AssertWindowHasOneTab(0, &url);
63   }
64 
AssertWindowHasOneTab(int window_index,GURL * url)65   void AssertWindowHasOneTab(int window_index, GURL* url) {
66     scoped_refptr<BrowserProxy> browser_proxy(
67         automation()->GetBrowserWindow(window_index));
68     ASSERT_TRUE(browser_proxy.get());
69 
70     int tab_count;
71     ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
72     ASSERT_EQ(1, tab_count);
73 
74     int active_tab_index;
75     ASSERT_TRUE(browser_proxy->GetActiveTabIndex(&active_tab_index));
76     ASSERT_EQ(0, active_tab_index);
77 
78     scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetActiveTab());
79     ASSERT_TRUE(tab_proxy.get());
80     ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
81         TestTimeouts::action_max_timeout_ms()));
82 
83     ASSERT_TRUE(tab_proxy->GetCurrentURL(url));
84   }
85 
86   GURL url1_;
87   GURL url2_;
88   GURL url3_;
89 
90  private:
91   DISALLOW_COPY_AND_ASSIGN(SessionRestoreUITest);
92 };
93 
TEST_F(SessionRestoreUITest,Basic)94 TEST_F(SessionRestoreUITest, Basic) {
95   NavigateToURL(url1_);
96   NavigateToURL(url2_);
97 
98   QuitBrowserAndRestore(1);
99 
100   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
101   // active windows returns NULL.
102   int window_count;
103   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
104   ASSERT_EQ(1, window_count);
105   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
106   ASSERT_TRUE(browser_proxy.get());
107   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
108   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
109       TestTimeouts::action_max_timeout_ms()));
110 
111   ASSERT_EQ(url2_, GetActiveTabURL());
112   ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab_proxy->GoBack());
113   ASSERT_EQ(url1_, GetActiveTabURL());
114 }
115 
TEST_F(SessionRestoreUITest,RestoresForwardAndBackwardNavs)116 TEST_F(SessionRestoreUITest, RestoresForwardAndBackwardNavs) {
117   NavigateToURL(url1_);
118   NavigateToURL(url2_);
119   NavigateToURL(url3_);
120 
121   scoped_refptr<TabProxy> active_tab(GetActiveTab());
122   ASSERT_TRUE(active_tab.get());
123   ASSERT_TRUE(active_tab->GoBack());
124 
125   QuitBrowserAndRestore(1);
126 
127   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
128   // active windows returns NULL.
129   int window_count;
130   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
131   ASSERT_EQ(1, window_count);
132   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
133   ASSERT_TRUE(browser_proxy.get());
134   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
135   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
136       TestTimeouts::action_max_timeout_ms()));
137 
138   ASSERT_TRUE(GetActiveTabURL() == url2_);
139   ASSERT_TRUE(tab_proxy->GoForward());
140   ASSERT_TRUE(GetActiveTabURL() == url3_);
141   ASSERT_TRUE(tab_proxy->GoBack());
142   ASSERT_TRUE(GetActiveTabURL() == url2_);
143   ASSERT_TRUE(tab_proxy->GoBack());
144   ASSERT_TRUE(GetActiveTabURL() == url1_);
145 }
146 
147 // Tests that the SiteInstances used for entries in a restored tab's history
148 // are given appropriate max page IDs, so that going back to a restored
149 // cross-site page and then forward again works.  (Bug 1204135)
TEST_F(SessionRestoreUITest,RestoresCrossSiteForwardAndBackwardNavs)150 TEST_F(SessionRestoreUITest, RestoresCrossSiteForwardAndBackwardNavs) {
151   net::TestServer test_server(net::TestServer::TYPE_HTTP,
152                               FilePath(FILE_PATH_LITERAL("chrome/test/data")));
153   ASSERT_TRUE(test_server.Start());
154 
155   GURL cross_site_url(test_server.GetURL("files/title2.html"));
156 
157   // Visit URLs on different sites.
158   NavigateToURL(url1_);
159   NavigateToURL(cross_site_url);
160   NavigateToURL(url2_);
161 
162   scoped_refptr<TabProxy> active_tab(GetActiveTab());
163   ASSERT_TRUE(active_tab.get());
164   ASSERT_TRUE(active_tab->GoBack());
165 
166   QuitBrowserAndRestore(1);
167 
168   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
169   // active windows returns NULL.
170   int window_count;
171   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
172   ASSERT_EQ(1, window_count);
173   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
174   ASSERT_TRUE(browser_proxy.get());
175   int tab_count;
176   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
177   ASSERT_EQ(1, tab_count);
178   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
179   ASSERT_TRUE(tab_proxy.get());
180   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
181       TestTimeouts::action_max_timeout_ms()));
182 
183   // Check that back and forward work as expected.
184   GURL url;
185   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
186   ASSERT_EQ(cross_site_url, url);
187 
188   ASSERT_TRUE(tab_proxy->GoBack());
189   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
190   ASSERT_EQ(url1_, url);
191 
192   ASSERT_TRUE(tab_proxy->GoForward());
193   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
194   ASSERT_EQ(cross_site_url, url);
195 
196   ASSERT_TRUE(tab_proxy->GoForward());
197   ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
198   ASSERT_EQ(url2_, url);
199 }
200 
TEST_F(SessionRestoreUITest,TwoTabsSecondSelected)201 TEST_F(SessionRestoreUITest, TwoTabsSecondSelected) {
202   NavigateToURL(url1_);
203 
204   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
205   // active windows returns NULL.
206   int window_count;
207   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
208   ASSERT_EQ(1, window_count);
209   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
210   ASSERT_TRUE(browser_proxy.get());
211 
212   ASSERT_TRUE(browser_proxy->AppendTab(url2_));
213 
214   QuitBrowserAndRestore(2);
215   browser_proxy = NULL;
216 
217   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
218   ASSERT_EQ(1, window_count);
219   browser_proxy = automation()->GetBrowserWindow(0);
220 
221   int tab_count;
222   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
223   ASSERT_EQ(2, tab_count);
224 
225   int active_tab_index;
226   ASSERT_TRUE(browser_proxy->GetActiveTabIndex(&active_tab_index));
227   ASSERT_EQ(1, active_tab_index);
228 
229   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetActiveTab());
230   ASSERT_TRUE(tab_proxy.get());
231   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
232       TestTimeouts::action_max_timeout_ms()));
233 
234   ASSERT_EQ(url2_, GetActiveTabURL());
235 
236   ASSERT_TRUE(browser_proxy->ActivateTab(0));
237   tab_proxy = browser_proxy->GetActiveTab();
238   ASSERT_TRUE(tab_proxy.get());
239   ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
240       TestTimeouts::action_max_timeout_ms()));
241 
242   ASSERT_EQ(url1_, GetActiveTabURL());
243 }
244 
245 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
TEST_F(SessionRestoreUITest,ClosedTabStaysClosed)246 TEST_F(SessionRestoreUITest, ClosedTabStaysClosed) {
247   NavigateToURL(url1_);
248 
249   // NOTE: Don't use GetActiveWindow here, when run with the screen locked
250   // active windows returns NULL.
251   int window_count;
252   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
253   ASSERT_EQ(1, window_count);
254   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
255   ASSERT_TRUE(browser_proxy.get());
256   scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
257   ASSERT_TRUE(tab_proxy.get());
258 
259   ASSERT_TRUE(browser_proxy->AppendTab(url2_));
260 
261   scoped_refptr<TabProxy> active_tab(browser_proxy->GetActiveTab());
262   ASSERT_TRUE(active_tab.get());
263   ASSERT_TRUE(active_tab->Close(true));
264 
265   QuitBrowserAndRestore(1);
266   browser_proxy = NULL;
267   tab_proxy = NULL;
268 
269   AssertOneWindowWithOneTab();
270 
271   ASSERT_EQ(url1_, GetActiveTabURL());
272 }
273 
274 // Creates a tabbed browser and popup and makes sure we restore both.
TEST_F(SessionRestoreUITest,NormalAndPopup)275 TEST_F(SessionRestoreUITest, NormalAndPopup) {
276   if (!browser_defaults::kRestorePopups)
277     return;  // Test only applicable if restoring popups.
278 
279   NavigateToURL(url1_);
280 
281   // Make sure we have one window.
282   int window_count;
283   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
284   ASSERT_EQ(1, window_count);
285 
286   // Open a popup.
287   ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_POPUP,
288                                                  true));
289   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
290   ASSERT_EQ(2, window_count);
291 
292   scoped_refptr<BrowserProxy> popup(automation()->GetBrowserWindow(1));
293   ASSERT_TRUE(popup.get());
294 
295   scoped_refptr<TabProxy> tab(popup->GetTab(0));
296   ASSERT_TRUE(tab.get());
297 
298   ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(url1_));
299 
300   // Simulate an exit by shuting down the session service. If we don't do this
301   // the first window close is treated as though the user closed the window
302   // and won't be restored.
303   ASSERT_TRUE(popup->ShutdownSessionService());
304 
305   tab = NULL;
306   popup = NULL;
307 
308   // Restart and make sure we have only one window with one tab and the url
309   // is url1_.
310   QuitBrowserAndRestore(1);
311 
312   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
313   ASSERT_EQ(2, window_count);
314 
315   scoped_refptr<BrowserProxy> browser_proxy1(
316       automation()->GetBrowserWindow(0));
317   ASSERT_TRUE(browser_proxy1.get());
318 
319   scoped_refptr<BrowserProxy> browser_proxy2(
320       automation()->GetBrowserWindow(1));
321   ASSERT_TRUE(browser_proxy2.get());
322 
323   Browser::Type type1, type2;
324   ASSERT_TRUE(browser_proxy1->GetType(&type1));
325   ASSERT_TRUE(browser_proxy2->GetType(&type2));
326 
327   // The order of whether the normal window or popup is first depends upon
328   // activation order, which is not necessarily consistant across runs.
329   if (type1 == Browser::TYPE_NORMAL) {
330     EXPECT_EQ(type2, Browser::TYPE_POPUP);
331   } else {
332     EXPECT_EQ(type1, Browser::TYPE_POPUP);
333     EXPECT_EQ(type2, Browser::TYPE_NORMAL);
334   }
335 }
336 
337 #if !defined(OS_MACOSX)
338 // This test doesn't apply to the Mac version; see
339 // LaunchAnotherBrowserBlockUntilClosed for details.
340 
341 // Launches an app window, closes tabbed browser, launches and makes sure
342 // we restore the tabbed browser url.
343 // Flaky: http://crbug.com/29110
TEST_F(SessionRestoreUITest,FLAKY_RestoreAfterClosingTabbedBrowserWithAppAndLaunching)344 TEST_F(SessionRestoreUITest,
345        FLAKY_RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
346   NavigateToURL(url1_);
347 
348   // Launch an app.
349 
350   bool include_testing_id_orig = include_testing_id_;
351   include_testing_id_ = false;
352   clear_profile_ = false;
353   CommandLine app_launch_arguments = launch_arguments_;
354   app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
355   LaunchAnotherBrowserBlockUntilClosed(app_launch_arguments);
356   ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
357 
358   // Close the first window. The only window left is the App window.
359   CloseWindow(0, 2);
360 
361   // Restore the session, which should bring back the first window with url1_.
362   // First restore the settings so we can connect to the browser.
363   include_testing_id_ = include_testing_id_orig;
364   // Restore the session with 1 tab.
365   QuitBrowserAndRestore(1);
366 
367   AssertOneWindowWithOneTab();
368 
369   ASSERT_EQ(url1_, GetActiveTabURL());
370 }
371 
372 #endif  // !OS_MACOSX
373 
374 // Creates two windows, closes one, restores, make sure only one window open.
TEST_F(SessionRestoreUITest,TwoWindowsCloseOneRestoreOnlyOne)375 TEST_F(SessionRestoreUITest, TwoWindowsCloseOneRestoreOnlyOne) {
376   NavigateToURL(url1_);
377 
378   // Make sure we have one window.
379   int window_count;
380   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
381   ASSERT_EQ(1, window_count);
382 
383   // Open a second window.
384   ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL,
385                                                  true));
386   ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
387   ASSERT_EQ(2, window_count);
388 
389   // Close it.
390   CloseWindow(1, 2);
391 
392   // Restart and make sure we have only one window with one tab and the url
393   // is url1_.
394   QuitBrowserAndRestore(1);
395 
396   AssertOneWindowWithOneTab();
397 
398   ASSERT_EQ(url1_, GetActiveTabURL());
399 }
400 
401 // Make sure after a restore the number of processes matches that of the number
402 // of processes running before the restore. This creates a new tab so that
403 // we should have two new tabs running.  (This test will pass in both
404 // process-per-site and process-per-site-instance, because we treat the new tab
405 // as a special case in process-per-site-instance so that it only ever uses one
406 // process.)
407 //
408 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
409 // Unfortunately, the fix at http://codereview.chromium.org/6546078
410 // breaks NTP background image refreshing, so ThemeSource had to revert to
411 // replacing the existing data source.
TEST_F(SessionRestoreUITest,FLAKY_ShareProcessesOnRestore)412 TEST_F(SessionRestoreUITest, FLAKY_ShareProcessesOnRestore) {
413   if (ProxyLauncher::in_process_renderer()) {
414     // No point in running this test in single process mode.
415     return;
416   }
417 
418   scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
419   ASSERT_TRUE(browser_proxy.get() != NULL);
420   int tab_count;
421   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
422 
423   // Create two new tabs.
424   ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_TAB));
425   ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_TAB));
426   int new_tab_count;
427   ASSERT_TRUE(browser_proxy->GetTabCount(&new_tab_count));
428   ASSERT_EQ(tab_count + 2, new_tab_count);
429 
430   int expected_process_count = 0;
431   ASSERT_TRUE(GetBrowserProcessCount(&expected_process_count));
432   int expected_tab_count = new_tab_count;
433 
434   // Restart.
435   browser_proxy = NULL;
436   QuitBrowserAndRestore(3);
437 
438   // Wait for each tab to finish being restored, then make sure the process
439   // count matches.
440   browser_proxy = automation()->GetBrowserWindow(0);
441   ASSERT_TRUE(browser_proxy.get() != NULL);
442   ASSERT_TRUE(browser_proxy->GetTabCount(&tab_count));
443   ASSERT_EQ(expected_tab_count, tab_count);
444 
445   for (int i = 0; i < expected_tab_count; ++i) {
446     scoped_refptr<TabProxy> tab_proxy(browser_proxy->GetTab(i));
447     ASSERT_TRUE(tab_proxy.get() != NULL);
448     ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored(
449                     TestTimeouts::action_max_timeout_ms()));
450   }
451 
452   int process_count = 0;
453   ASSERT_TRUE(GetBrowserProcessCount(&process_count));
454   ASSERT_EQ(expected_process_count, process_count);
455 }
456 
457 }  // namespace
458