popup_blocker_browsertest.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
1// Copyright 2013 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/files/file_path.h" 7#include "base/message_loop/message_loop.h" 8#include "base/path_service.h" 9#include "base/strings/utf_string_conversions.h" 10#include "chrome/browser/autocomplete/autocomplete_match.h" 11#include "chrome/browser/autocomplete/autocomplete_result.h" 12#include "chrome/browser/chrome_notification_types.h" 13#include "chrome/browser/content_settings/host_content_settings_map.h" 14#include "chrome/browser/content_settings/tab_specific_content_settings.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/browser/search_engines/template_url_service_factory.h" 17#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" 18#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" 19#include "chrome/browser/ui/browser.h" 20#include "chrome/browser/ui/browser_commands.h" 21#include "chrome/browser/ui/browser_finder.h" 22#include "chrome/browser/ui/browser_window.h" 23#include "chrome/browser/ui/omnibox/location_bar.h" 24#include "chrome/browser/ui/omnibox/omnibox_edit_model.h" 25#include "chrome/browser/ui/omnibox/omnibox_view.h" 26#include "chrome/browser/ui/tabs/tab_strip_model.h" 27#include "chrome/common/chrome_paths.h" 28#include "chrome/common/chrome_switches.h" 29#include "chrome/test/base/in_process_browser_test.h" 30#include "chrome/test/base/ui_test_utils.h" 31#include "content/public/browser/notification_registrar.h" 32#include "content/public/browser/notification_service.h" 33#include "content/public/browser/web_contents.h" 34#include "content/public/browser/web_contents_view.h" 35#include "content/public/common/url_constants.h" 36#include "content/public/test/browser_test_utils.h" 37#include "testing/gtest/include/gtest/gtest.h" 38 39using content::WebContents; 40 41namespace { 42 43static const base::FilePath::CharType* kTestDir = 44 FILE_PATH_LITERAL("popup_blocker"); 45 46// Counts the number of RenderViewHosts created. 47class CountRenderViewHosts : public content::NotificationObserver { 48 public: 49 CountRenderViewHosts() 50 : count_(0) { 51 registrar_.Add(this, 52 content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, 53 content::NotificationService::AllSources()); 54 } 55 virtual ~CountRenderViewHosts() {} 56 57 int GetRenderViewHostCreatedCount() const { return count_; } 58 59 private: 60 virtual void Observe(int type, 61 const content::NotificationSource& source, 62 const content::NotificationDetails& details) OVERRIDE { 63 count_++; 64 } 65 66 content::NotificationRegistrar registrar_; 67 68 int count_; 69 70 DISALLOW_COPY_AND_ASSIGN(CountRenderViewHosts); 71}; 72 73class PopupBlockerBrowserTest : public InProcessBrowserTest { 74 public: 75 PopupBlockerBrowserTest() {} 76 77 // Returns a url that shows one popup. 78 GURL GetTestURL() { 79 return ui_test_utils::GetTestUrl( 80 base::FilePath(kTestDir), 81 base::FilePath(FILE_PATH_LITERAL("popup-blocked-to-post-blank.html"))); 82 } 83 84 std::vector<WebContents*> GetBlockedContents(Browser* browser) { 85 // Do a round trip to the renderer first to flush any in-flight IPCs to 86 // create a to-be-blocked window. 87 WebContents* tab = browser->tab_strip_model()->GetActiveWebContents(); 88 CHECK(content::ExecuteScript(tab, std::string())); 89 BlockedContentTabHelper* blocked_content_tab_helper = 90 BlockedContentTabHelper::FromWebContents(tab); 91 std::vector<WebContents*> blocked_contents; 92 blocked_content_tab_helper->GetBlockedContents(&blocked_contents); 93 return blocked_contents; 94 } 95 96 void NavigateAndCheckPopupShown(Browser* browser, const GURL& url) { 97 content::WindowedNotificationObserver observer( 98 chrome::NOTIFICATION_TAB_ADDED, 99 content::NotificationService::AllSources()); 100 ui_test_utils::NavigateToURL(browser, url); 101 observer.Wait(); 102 103 ASSERT_EQ(2u, chrome::GetBrowserCount(browser->profile(), 104 browser->host_desktop_type())); 105 106 std::vector<WebContents*> blocked_contents = GetBlockedContents(browser); 107 ASSERT_TRUE(blocked_contents.empty()); 108 } 109 110 void BasicTest(Browser* browser, const GURL& url) { 111 ui_test_utils::NavigateToURL(browser, url); 112 113 // If the popup blocker blocked the blank post, there should be only one 114 // tab in only one browser window and the URL of current tab must be equal 115 // to the original URL. 116 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 117 browser->host_desktop_type())); 118 EXPECT_EQ(1, browser->tab_strip_model()->count()); 119 WebContents* web_contents = 120 browser->tab_strip_model()->GetActiveWebContents(); 121 EXPECT_EQ(url, web_contents->GetURL()); 122 123 std::vector<WebContents*> blocked_contents = GetBlockedContents(browser); 124 ASSERT_EQ(1u, blocked_contents.size()); 125 126 content::WindowedNotificationObserver observer( 127 chrome::NOTIFICATION_TAB_ADDED, 128 content::NotificationService::AllSources()); 129 130 BlockedContentTabHelper* blocked_content_tab_helper = 131 BlockedContentTabHelper::FromWebContents(web_contents); 132 blocked_content_tab_helper->LaunchForContents(blocked_contents[0]); 133 134 observer.Wait(); 135 } 136}; 137 138IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, PopupBlockedPostBlank) { 139 BasicTest(browser(), GetTestURL()); 140} 141 142IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 143 PopupBlockedPostBlankIncognito) { 144 BasicTest(CreateIncognitoBrowser(), GetTestURL()); 145} 146 147IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 148 PopupBlockedFakeClickOnAnchor) { 149 GURL url(ui_test_utils::GetTestUrl( 150 base::FilePath(kTestDir), 151 base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor.html")))); 152 BasicTest(browser(), url); 153} 154 155IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, MultiplePopups) { 156 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 157 kTestDir), base::FilePath(FILE_PATH_LITERAL("popup-many.html")))); 158 ui_test_utils::NavigateToURL(browser(), url); 159 std::vector<WebContents*> blocked_contents = GetBlockedContents(browser()); 160 ASSERT_EQ(2u, blocked_contents.size()); 161} 162 163// Verify that popups are launched on browser back button. 164IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 165 AllowPopupThroughContentSetting) { 166 GURL url(GetTestURL()); 167 browser()->profile()->GetHostContentSettingsMap() 168 ->SetContentSetting(ContentSettingsPattern::FromURL(url), 169 ContentSettingsPattern::Wildcard(), 170 CONTENT_SETTINGS_TYPE_POPUPS, 171 std::string(), 172 CONTENT_SETTING_ALLOW); 173 174 NavigateAndCheckPopupShown(browser(), url); 175} 176 177IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, PopupsLaunchWhenTabIsClosed) { 178 CommandLine::ForCurrentProcess()->AppendSwitch( 179 switches::kDisablePopupBlocking); 180 GURL url = ui_test_utils::GetTestUrl( 181 base::FilePath(kTestDir), 182 base::FilePath(FILE_PATH_LITERAL("popup-on-unload.html"))); 183 ui_test_utils::NavigateToURL(browser(), url); 184 185 NavigateAndCheckPopupShown(browser(), GURL(content::kAboutBlankURL)); 186} 187 188// Verify that when you unblock popup, the popup shows in history and omnibox. 189IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 190 UnblockedPopupShowsInHistoryAndOmnibox) { 191 CommandLine::ForCurrentProcess()->AppendSwitch( 192 switches::kDisablePopupBlocking); 193 GURL url(GetTestURL()); 194 NavigateAndCheckPopupShown(browser(), url); 195 196 std::string search_string = 197 "data:text/html,<title>Popup Success!</title>you should not see this " 198 "message if popup blocker is enabled"; 199 200 ui_test_utils::HistoryEnumerator history(browser()->profile()); 201 std::vector<GURL>& history_urls = history.urls(); 202 ASSERT_EQ(2u, history_urls.size()); 203 ASSERT_EQ(GURL(search_string), history_urls[0]); 204 ASSERT_EQ(url, history_urls[1]); 205 206 TemplateURLService* service = TemplateURLServiceFactory::GetForProfile( 207 browser()->profile()); 208 ui_test_utils::WaitForTemplateURLServiceToLoad(service); 209 LocationBar* location_bar = browser()->window()->GetLocationBar(); 210 ui_test_utils::SendToOmniboxAndSubmit(location_bar, search_string); 211 OmniboxEditModel* model = location_bar->GetLocationEntry()->model(); 212 EXPECT_EQ(GURL(search_string), model->CurrentMatch(NULL).destination_url); 213 EXPECT_EQ(ASCIIToUTF16(search_string), model->CurrentMatch(NULL).contents); 214} 215 216class BetterPopupBlockerBrowserTest : public PopupBlockerBrowserTest { 217 public: 218 BetterPopupBlockerBrowserTest() {} 219 virtual ~BetterPopupBlockerBrowserTest() {} 220 221 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 222 PopupBlockerBrowserTest::SetUpCommandLine(command_line); 223 command_line->AppendSwitch(switches::kEnableBetterPopupBlocking); 224 } 225 226 private: 227 DISALLOW_COPY_AND_ASSIGN(BetterPopupBlockerBrowserTest); 228}; 229 230IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest, 231 BlockWebContentsCreation) { 232 CountRenderViewHosts counter; 233 234 ui_test_utils::NavigateToURL(browser(), GetTestURL()); 235 236 // Wait until the request actually has hit the popup blocker. The 237 // NavigateToURL call above returns as soon as the main tab stopped loading 238 // which can happen before the popup request was processed. 239 WebContents* web_contents = 240 browser()->tab_strip_model()->GetActiveWebContents(); 241 PopupBlockerTabHelper* popup_blocker_helper = 242 PopupBlockerTabHelper::FromWebContents(web_contents); 243 if (!popup_blocker_helper->GetBlockedPopupsCount()) { 244 content::WindowedNotificationObserver observer( 245 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 246 content::NotificationService::AllSources()); 247 observer.Wait(); 248 } 249 250 // If the popup blocker blocked the blank post, there should be only one tab. 251 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 252 browser()->host_desktop_type())); 253 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 254 EXPECT_EQ(GetTestURL(), web_contents->GetURL()); 255 256 // And no new RVH created. 257 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 258 259 content::WindowedNotificationObserver observer( 260 chrome::NOTIFICATION_TAB_ADDED, 261 content::NotificationService::AllSources()); 262 263 // Launch the blocked popup. 264 EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount()); 265 std::map<int32, GURL> blocked_requests = 266 popup_blocker_helper->GetBlockedPopupRequests(); 267 std::map<int32, GURL>::const_iterator iter = blocked_requests.begin(); 268 popup_blocker_helper->ShowBlockedPopup(iter->first); 269 270 observer.Wait(); 271} 272 273IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest, 274 PopupBlockedFakeClickOnAnchorNoTarget) { 275 GURL url(ui_test_utils::GetTestUrl( 276 base::FilePath(kTestDir), 277 base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor2.html")))); 278 279 CountRenderViewHosts counter; 280 281 ui_test_utils::NavigateToURL(browser(), url); 282 283 // If the popup blocker blocked the blank post, there should be only one tab. 284 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 285 browser()->host_desktop_type())); 286 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 287 WebContents* web_contents = 288 browser()->tab_strip_model()->GetActiveWebContents(); 289 EXPECT_EQ(url, web_contents->GetURL()); 290 291 // And no new RVH created. 292 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 293 294 content::WindowedNotificationObserver observer( 295 chrome::NOTIFICATION_TAB_ADDED, 296 content::NotificationService::AllSources()); 297 298 // Launch the blocked popup. 299 PopupBlockerTabHelper* popup_blocker_helper = 300 PopupBlockerTabHelper::FromWebContents(web_contents); 301 EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount()); 302 std::map<int32, GURL> blocked_requests = 303 popup_blocker_helper->GetBlockedPopupRequests(); 304 std::map<int32, GURL>::const_iterator iter = blocked_requests.begin(); 305 popup_blocker_helper->ShowBlockedPopup(iter->first); 306 307 observer.Wait(); 308} 309 310IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest, WindowFeatures) { 311 GURL url(ui_test_utils::GetTestUrl( 312 base::FilePath(kTestDir), 313 base::FilePath(FILE_PATH_LITERAL("popup-window-open.html")))); 314 315 CountRenderViewHosts counter; 316 317 ui_test_utils::NavigateToURL(browser(), url); 318 319 // If the popup blocker blocked the blank post, there should be only one tab. 320 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 321 browser()->host_desktop_type())); 322 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 323 WebContents* web_contents = 324 browser()->tab_strip_model()->GetActiveWebContents(); 325 EXPECT_EQ(url, web_contents->GetURL()); 326 327 // And no new RVH created. 328 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 329 330 content::WindowedNotificationObserver observer( 331 chrome::NOTIFICATION_TAB_ADDED, 332 content::NotificationService::AllSources()); 333 ui_test_utils::BrowserAddedObserver browser_observer; 334 335 // Launch the blocked popup. 336 PopupBlockerTabHelper* popup_blocker_helper = 337 PopupBlockerTabHelper::FromWebContents(web_contents); 338 EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount()); 339 std::map<int32, GURL> blocked_requests = 340 popup_blocker_helper->GetBlockedPopupRequests(); 341 std::map<int32, GURL>::const_iterator iter = blocked_requests.begin(); 342 popup_blocker_helper->ShowBlockedPopup(iter->first); 343 344 observer.Wait(); 345 Browser* new_browser = browser_observer.WaitForSingleNewBrowser(); 346 347 // Check that the new popup has (roughly) the requested size. 348 web_contents = new_browser->tab_strip_model()->GetActiveWebContents(); 349 gfx::Size window_size = web_contents->GetView()->GetContainerSize(); 350 EXPECT_TRUE(349 <= window_size.width() && window_size.width() <= 351); 351 EXPECT_TRUE(249 <= window_size.height() && window_size.height() <= 251); 352} 353 354IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest, CorrectReferrer) { 355 GURL url(ui_test_utils::GetTestUrl( 356 base::FilePath(kTestDir), 357 base::FilePath(FILE_PATH_LITERAL("popup-referrer.html")))); 358 359 CountRenderViewHosts counter; 360 361 ui_test_utils::NavigateToURL(browser(), url); 362 363 // If the popup blocker blocked the blank post, there should be only one tab. 364 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 365 browser()->host_desktop_type())); 366 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 367 WebContents* web_contents = 368 browser()->tab_strip_model()->GetActiveWebContents(); 369 EXPECT_EQ(url, web_contents->GetURL()); 370 371 // And no new RVH created. 372 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 373 374 content::WindowedNotificationObserver observer( 375 chrome::NOTIFICATION_TAB_ADDED, 376 content::NotificationService::AllSources()); 377 ui_test_utils::BrowserAddedObserver browser_observer; 378 379 // Launch the blocked popup. 380 PopupBlockerTabHelper* popup_blocker_helper = 381 PopupBlockerTabHelper::FromWebContents(web_contents); 382 EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount()); 383 std::map<int32, GURL> blocked_requests = 384 popup_blocker_helper->GetBlockedPopupRequests(); 385 std::map<int32, GURL>::const_iterator iter = blocked_requests.begin(); 386 popup_blocker_helper->ShowBlockedPopup(iter->first); 387 388 observer.Wait(); 389 Browser* new_browser = browser_observer.WaitForSingleNewBrowser(); 390 391 // Check that the referrer was correctly set. 392 web_contents = new_browser->tab_strip_model()->GetActiveWebContents(); 393 base::string16 expected_title(base::ASCIIToUTF16("PASS")); 394 content::TitleWatcher title_watcher(web_contents, expected_title); 395 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 396} 397 398IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest, WindowFeaturesBarProps) { 399 GURL url(ui_test_utils::GetTestUrl( 400 base::FilePath(kTestDir), 401 base::FilePath(FILE_PATH_LITERAL("popup-windowfeatures.html")))); 402 403 CountRenderViewHosts counter; 404 405 ui_test_utils::NavigateToURL(browser(), url); 406 407 // If the popup blocker blocked the blank post, there should be only one tab. 408 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 409 browser()->host_desktop_type())); 410 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 411 WebContents* web_contents = 412 browser()->tab_strip_model()->GetActiveWebContents(); 413 EXPECT_EQ(url, web_contents->GetURL()); 414 415 // And no new RVH created. 416 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 417 418 content::WindowedNotificationObserver observer( 419 chrome::NOTIFICATION_TAB_ADDED, 420 content::NotificationService::AllSources()); 421 ui_test_utils::BrowserAddedObserver browser_observer; 422 423 // Launch the blocked popup. 424 PopupBlockerTabHelper* popup_blocker_helper = 425 PopupBlockerTabHelper::FromWebContents(web_contents); 426 EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount()); 427 std::map<int32, GURL> blocked_requests = 428 popup_blocker_helper->GetBlockedPopupRequests(); 429 std::map<int32, GURL>::const_iterator iter = blocked_requests.begin(); 430 popup_blocker_helper->ShowBlockedPopup(iter->first); 431 432 observer.Wait(); 433 Browser* new_browser = browser_observer.WaitForSingleNewBrowser(); 434 435 // Check that the referrer was correctly set. 436 web_contents = new_browser->tab_strip_model()->GetActiveWebContents(); 437 base::string16 expected_title(base::ASCIIToUTF16("PASS")); 438 content::TitleWatcher title_watcher(web_contents, expected_title); 439 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 440} 441 442} // namespace 443