1 // Copyright 2014 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 "chrome/browser/chrome_notification_types.h" 6 #include "chrome/browser/sessions/tab_restore_service.h" 7 #include "chrome/browser/sessions/tab_restore_service_delegate.h" 8 #include "chrome/browser/sessions/tab_restore_service_factory.h" 9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser_commands.h" 11 #include "chrome/browser/ui/browser_list.h" 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" 13 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" 14 #include "chrome/test/base/in_process_browser_test.h" 15 #include "chrome/test/base/interactive_test_utils.h" 16 #include "content/public/browser/web_contents.h" 17 #include "content/public/common/url_constants.h" 18 #include "content/public/test/browser_test_utils.h" 19 20 typedef InProcessBrowserTest BrowserTabRestoreTest; 21 22 void AwaitTabsReady(content::DOMMessageQueue* message_queue, int tabs) { 23 for (int i = 0; i < tabs; ++i) { 24 std::string message; 25 EXPECT_TRUE(message_queue->WaitForMessage(&message)); 26 EXPECT_EQ("\"READY\"", message); 27 } 28 } 29 30 void CheckVisbility(TabStripModel* tab_strip_model, int visible_index) { 31 for (int i = 0; i < tab_strip_model->count(); ++i) { 32 content::WebContents* contents = tab_strip_model->GetWebContentsAt(i); 33 std::string document_visibility_state; 34 const char kGetStateJS[] = "window.domAutomationController.send(" 35 "window.document.visibilityState);"; 36 EXPECT_TRUE(content::ExecuteScriptAndExtractString( 37 contents, kGetStateJS, &document_visibility_state)); 38 if (i == visible_index) { 39 EXPECT_EQ("visible", document_visibility_state); 40 } else { 41 EXPECT_EQ("hidden", document_visibility_state); 42 } 43 } 44 } 45 46 void CreateTestTabs(Browser* browser) { 47 GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(), 48 base::FilePath(FILE_PATH_LITERAL("tab-restore-visibilty.html")))); 49 ui_test_utils::NavigateToURLWithDisposition( 50 browser, test_page, NEW_FOREGROUND_TAB, 51 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 52 ui_test_utils::NavigateToURLWithDisposition( 53 browser, test_page, NEW_BACKGROUND_TAB, 54 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 55 } 56 57 void CloseBrowser(Browser* browser) { 58 content::WindowedNotificationObserver close_observer( 59 chrome::NOTIFICATION_BROWSER_CLOSED, 60 content::Source<Browser>(browser)); 61 chrome::CloseWindow(browser); 62 close_observer.Wait(); 63 } 64 65 IN_PROC_BROWSER_TEST_F(BrowserTabRestoreTest, RecentTabsMenuTabDisposition) { 66 // Create tabs. 67 CreateTestTabs(browser()); 68 EXPECT_EQ(3, browser()->tab_strip_model()->count()); 69 70 // Create a new browser. 71 ui_test_utils::NavigateToURLWithDisposition( 72 browser(), 73 GURL(url::kAboutBlankURL), 74 NEW_WINDOW, 75 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); 76 BrowserList* active_browser_list = 77 BrowserList::GetInstance(browser()->host_desktop_type()); 78 EXPECT_EQ(2u, active_browser_list->size()); 79 80 // Close the first browser. 81 CloseBrowser(browser()); 82 EXPECT_EQ(1u, active_browser_list->size()); 83 84 // Restore tabs using the browser's recent tabs menu. 85 content::DOMMessageQueue queue; 86 Browser* browser = active_browser_list->get(0); 87 RecentTabsSubMenuModel menu(NULL, browser, NULL); 88 menu.ExecuteCommand( 89 RecentTabsSubMenuModel::GetFirstRecentTabsCommandId(), 0); 90 AwaitTabsReady(&queue, 2); 91 92 // There should be 3 restored tabs in the new browser. 93 EXPECT_EQ(2u, active_browser_list->size()); 94 browser = active_browser_list->get(1); 95 EXPECT_EQ(3, browser->tab_strip_model()->count()); 96 97 // The middle tab only should have visible disposition. 98 CheckVisbility(browser->tab_strip_model(), 1); 99 } 100 101 IN_PROC_BROWSER_TEST_F(BrowserTabRestoreTest, DelegateRestoreTabDisposition) { 102 // Create tabs. 103 CreateTestTabs(browser()); 104 EXPECT_EQ(3, browser()->tab_strip_model()->count()); 105 106 // Create a new browser. 107 ui_test_utils::NavigateToURLWithDisposition( 108 browser(), 109 GURL(url::kAboutBlankURL), 110 NEW_WINDOW, 111 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER); 112 BrowserList* active_browser_list = 113 BrowserList::GetInstance(browser()->host_desktop_type()); 114 EXPECT_EQ(2u, active_browser_list->size()); 115 116 // Close the first browser. 117 CloseBrowser(browser()); 118 EXPECT_EQ(1u, active_browser_list->size()); 119 120 // Check the browser has a delegated restore service. 121 Browser* browser = active_browser_list->get(0); 122 TabRestoreService* service = 123 TabRestoreServiceFactory::GetForProfile(browser->profile()); 124 bool has_tab_restore_service = !!service; 125 ASSERT_TRUE(has_tab_restore_service); 126 TabRestoreServiceDelegate* delegate = 127 TabRestoreServiceDelegate::FindDelegateForWebContents( 128 browser->tab_strip_model()->GetActiveWebContents()); 129 bool has_tab_restore_delegate = !!delegate; 130 ASSERT_TRUE(has_tab_restore_delegate); 131 132 // Restore tabs using that delegated restore service. 133 content::DOMMessageQueue queue; 134 service->RestoreMostRecentEntry( 135 delegate, browser->host_desktop_type()); 136 AwaitTabsReady(&queue, 2); 137 138 // There should be 3 restored tabs in the new browser. 139 EXPECT_EQ(2u, active_browser_list->size()); 140 browser = active_browser_list->get(1); 141 EXPECT_EQ(3, browser->tab_strip_model()->count()); 142 143 // The middle tab only should have visible disposition. 144 CheckVisbility(browser->tab_strip_model(), 1); 145 } 146