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 "chrome/app/chrome_command_ids.h" 6 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 7 #include "chrome/browser/ui/browser_command_controller.h" 8 #include "chrome/browser/ui/browser_commands.h" 9 #include "chrome/browser/ui/browser_finder.h" 10 #include "chrome/browser/ui/tabs/tab_strip_model.h" 11 #include "chrome/common/url_constants.h" 12 #include "chrome/test/base/browser_with_test_window_test.h" 13 #include "chrome/test/base/testing_profile.h" 14 #include "components/bookmarks/browser/bookmark_model.h" 15 #include "components/bookmarks/test/bookmark_test_helpers.h" 16 #include "content/public/browser/navigation_controller.h" 17 #include "content/public/browser/navigation_entry.h" 18 #include "content/public/browser/web_contents.h" 19 20 typedef BrowserWithTestWindowTest BrowserCommandsTest; 21 22 using content::OpenURLParams; 23 using content::Referrer; 24 using content::WebContents; 25 26 // Tests IDC_SELECT_TAB_0, IDC_SELECT_NEXT_TAB, IDC_SELECT_PREVIOUS_TAB and 27 // IDC_SELECT_LAST_TAB. 28 TEST_F(BrowserCommandsTest, TabNavigationAccelerators) { 29 GURL about_blank(url::kAboutBlankURL); 30 31 // Create three tabs. 32 AddTab(browser(), about_blank); 33 AddTab(browser(), about_blank); 34 AddTab(browser(), about_blank); 35 36 // Select the second tab. 37 browser()->tab_strip_model()->ActivateTabAt(1, false); 38 39 CommandUpdater* updater = browser()->command_controller()->command_updater(); 40 41 // Navigate to the first tab using an accelerator. 42 updater->ExecuteCommand(IDC_SELECT_TAB_0); 43 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 44 45 // Navigate to the second tab using the next accelerators. 46 updater->ExecuteCommand(IDC_SELECT_NEXT_TAB); 47 ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); 48 49 // Navigate back to the first tab using the previous accelerators. 50 updater->ExecuteCommand(IDC_SELECT_PREVIOUS_TAB); 51 ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); 52 53 // Navigate to the last tab using the select last accelerator. 54 updater->ExecuteCommand(IDC_SELECT_LAST_TAB); 55 ASSERT_EQ(2, browser()->tab_strip_model()->active_index()); 56 } 57 58 // Tests IDC_DUPLICATE_TAB. 59 TEST_F(BrowserCommandsTest, DuplicateTab) { 60 GURL url1("http://foo/1"); 61 GURL url2("http://foo/2"); 62 GURL url3("http://foo/3"); 63 GURL url4("http://foo/4"); 64 65 // Navigate to three urls, plus a pending URL that hasn't committed. 66 AddTab(browser(), url1); 67 NavigateAndCommitActiveTab(url2); 68 NavigateAndCommitActiveTab(url3); 69 content::NavigationController& orig_controller = 70 browser()->tab_strip_model()->GetWebContentsAt(0)->GetController(); 71 orig_controller.LoadURL( 72 url4, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); 73 EXPECT_EQ(3, orig_controller.GetEntryCount()); 74 EXPECT_TRUE(orig_controller.GetPendingEntry()); 75 76 size_t initial_window_count = chrome::GetTotalBrowserCount(); 77 78 // Duplicate the tab. 79 chrome::ExecuteCommand(browser(), IDC_DUPLICATE_TAB); 80 81 // The duplicated tab should not end up in a new window. 82 size_t window_count = chrome::GetTotalBrowserCount(); 83 ASSERT_EQ(initial_window_count, window_count); 84 85 // And we should have a newly duplicated tab. 86 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 87 88 // Verify the stack of urls. 89 content::NavigationController& controller = 90 browser()->tab_strip_model()->GetWebContentsAt(1)->GetController(); 91 EXPECT_EQ(3, controller.GetEntryCount()); 92 EXPECT_EQ(2, controller.GetCurrentEntryIndex()); 93 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); 94 EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL()); 95 EXPECT_EQ(url3, controller.GetEntryAtIndex(2)->GetURL()); 96 EXPECT_FALSE(controller.GetPendingEntry()); 97 } 98 99 // Tests IDC_VIEW_SOURCE (See http://crbug.com/138140). 100 TEST_F(BrowserCommandsTest, ViewSource) { 101 GURL url1("http://foo/1"); 102 GURL url2("http://foo/2"); 103 104 // Navigate to a URL, plus a pending URL that hasn't committed. 105 AddTab(browser(), url1); 106 content::NavigationController& orig_controller = 107 browser()->tab_strip_model()->GetWebContentsAt(0)->GetController(); 108 orig_controller.LoadURL( 109 url2, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); 110 EXPECT_EQ(1, orig_controller.GetEntryCount()); 111 EXPECT_TRUE(orig_controller.GetPendingEntry()); 112 113 size_t initial_window_count = chrome::GetTotalBrowserCount(); 114 115 // View Source. 116 chrome::ExecuteCommand(browser(), IDC_VIEW_SOURCE); 117 118 // The view source tab should not end up in a new window. 119 size_t window_count = chrome::GetTotalBrowserCount(); 120 ASSERT_EQ(initial_window_count, window_count); 121 122 // And we should have a newly duplicated tab. 123 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 124 125 // Verify we are viewing the source of the last committed entry. 126 GURL view_source_url("view-source:http://foo/1"); 127 content::NavigationController& controller = 128 browser()->tab_strip_model()->GetWebContentsAt(1)->GetController(); 129 EXPECT_EQ(1, controller.GetEntryCount()); 130 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 131 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); 132 EXPECT_EQ(view_source_url, controller.GetEntryAtIndex(0)->GetVirtualURL()); 133 EXPECT_FALSE(controller.GetPendingEntry()); 134 } 135 136 TEST_F(BrowserCommandsTest, BookmarkCurrentPage) { 137 // We use profile() here, since it's a TestingProfile. 138 profile()->CreateBookmarkModel(true); 139 140 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile()); 141 test::WaitForBookmarkModelToLoad(model); 142 143 // Navigate to a url. 144 GURL url1("http://foo/1"); 145 AddTab(browser(), url1); 146 browser()->OpenURL(OpenURLParams( 147 url1, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 148 149 chrome::BookmarkCurrentPage(browser()); 150 151 // It should now be bookmarked in the bookmark model. 152 EXPECT_EQ(profile(), browser()->profile()); 153 EXPECT_TRUE(model->IsBookmarked(url1)); 154 } 155 156 // Tests back/forward in new tab (Control + Back/Forward button in the UI). 157 TEST_F(BrowserCommandsTest, BackForwardInNewTab) { 158 GURL url1("http://foo/1"); 159 GURL url2("http://foo/2"); 160 161 // Make a tab with the two pages navigated in it. 162 AddTab(browser(), url1); 163 NavigateAndCommitActiveTab(url2); 164 165 // Go back in a new background tab. 166 chrome::GoBack(browser(), NEW_BACKGROUND_TAB); 167 EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); 168 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 169 170 WebContents* zeroth = browser()->tab_strip_model()->GetWebContentsAt(0); 171 WebContents* first = browser()->tab_strip_model()->GetWebContentsAt(1); 172 173 // The original tab should be unchanged. 174 EXPECT_EQ(url2, zeroth->GetLastCommittedURL()); 175 EXPECT_TRUE(zeroth->GetController().CanGoBack()); 176 EXPECT_FALSE(zeroth->GetController().CanGoForward()); 177 178 // The new tab should be like the first one but navigated back. Since we 179 // didn't wait for the load to complete, we can't use GetLastCommittedURL. 180 EXPECT_EQ(url1, first->GetVisibleURL()); 181 EXPECT_FALSE(first->GetController().CanGoBack()); 182 EXPECT_TRUE(first->GetController().CanGoForward()); 183 184 // Select the second tab and make it go forward in a new background tab. 185 browser()->tab_strip_model()->ActivateTabAt(1, true); 186 // TODO(brettw) bug 11055: It should not be necessary to commit the load here, 187 // but because of this bug, it will assert later if we don't. When the bug is 188 // fixed, one of the three commits here related to this bug should be removed 189 // (to test both codepaths). 190 CommitPendingLoad(&first->GetController()); 191 EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); 192 chrome::GoForward(browser(), NEW_BACKGROUND_TAB); 193 194 // The previous tab should be unchanged and still in the foreground. 195 EXPECT_EQ(url1, first->GetLastCommittedURL()); 196 EXPECT_FALSE(first->GetController().CanGoBack()); 197 EXPECT_TRUE(first->GetController().CanGoForward()); 198 EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); 199 200 // There should be a new tab navigated forward. 201 ASSERT_EQ(3, browser()->tab_strip_model()->count()); 202 WebContents* second = browser()->tab_strip_model()->GetWebContentsAt(2); 203 // Since we didn't wait for load to complete, we can't use 204 // GetLastCommittedURL. 205 EXPECT_EQ(url2, second->GetVisibleURL()); 206 EXPECT_TRUE(second->GetController().CanGoBack()); 207 EXPECT_FALSE(second->GetController().CanGoForward()); 208 209 // Now do back in a new foreground tab. Don't bother re-checking every sngle 210 // thing above, just validate that it's opening properly. 211 browser()->tab_strip_model()->ActivateTabAt(2, true); 212 // TODO(brettw) bug 11055: see the comment above about why we need this. 213 CommitPendingLoad(&second->GetController()); 214 chrome::GoBack(browser(), NEW_FOREGROUND_TAB); 215 ASSERT_EQ(3, browser()->tab_strip_model()->active_index()); 216 ASSERT_EQ(url1, 217 browser()->tab_strip_model()->GetActiveWebContents()-> 218 GetVisibleURL()); 219 220 // Same thing again for forward. 221 // TODO(brettw) bug 11055: see the comment above about why we need this. 222 CommitPendingLoad(& 223 browser()->tab_strip_model()->GetActiveWebContents()->GetController()); 224 chrome::GoForward(browser(), NEW_FOREGROUND_TAB); 225 ASSERT_EQ(4, browser()->tab_strip_model()->active_index()); 226 ASSERT_EQ(url2, 227 browser()->tab_strip_model()->GetActiveWebContents()-> 228 GetVisibleURL()); 229 } 230