popup_blocker_browsertest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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.h" 8#include "base/path_service.h" 9#include "chrome/browser/autocomplete/autocomplete_match.h" 10#include "chrome/browser/autocomplete/autocomplete_result.h" 11#include "chrome/browser/chrome_notification_types.h" 12#include "chrome/browser/content_settings/host_content_settings_map.h" 13#include "chrome/browser/content_settings/tab_specific_content_settings.h" 14#include "chrome/browser/profiles/profile.h" 15#include "chrome/browser/search_engines/template_url_service_factory.h" 16#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" 17#include "chrome/browser/ui/browser.h" 18#include "chrome/browser/ui/browser_commands.h" 19#include "chrome/browser/ui/browser_finder.h" 20#include "chrome/browser/ui/browser_window.h" 21#include "chrome/browser/ui/omnibox/location_bar.h" 22#include "chrome/browser/ui/omnibox/omnibox_edit_model.h" 23#include "chrome/browser/ui/omnibox/omnibox_view.h" 24#include "chrome/browser/ui/tabs/tab_strip_model.h" 25#include "chrome/common/chrome_paths.h" 26#include "chrome/common/chrome_switches.h" 27#include "chrome/test/base/in_process_browser_test.h" 28#include "chrome/test/base/ui_test_utils.h" 29#include "content/public/browser/notification_registrar.h" 30#include "content/public/browser/notification_service.h" 31#include "content/public/browser/web_contents.h" 32#include "content/public/common/url_constants.h" 33#include "content/public/test/browser_test_utils.h" 34#include "testing/gtest/include/gtest/gtest.h" 35 36using content::WebContents; 37 38namespace { 39 40static const base::FilePath::CharType* kTestDir = 41 FILE_PATH_LITERAL("popup_blocker"); 42 43// Counts the number of RenderViewHosts created. 44class CountRenderViewHosts : public content::NotificationObserver { 45 public: 46 CountRenderViewHosts() 47 : count_(0) { 48 registrar_.Add(this, 49 content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, 50 content::NotificationService::AllSources()); 51 } 52 virtual ~CountRenderViewHosts() {} 53 54 int GetRenderViewHostCreatedCount() const { return count_; } 55 56 private: 57 virtual void Observe(int type, 58 const content::NotificationSource& source, 59 const content::NotificationDetails& details) OVERRIDE { 60 count_++; 61 } 62 63 content::NotificationRegistrar registrar_; 64 65 int count_; 66 67 DISALLOW_COPY_AND_ASSIGN(CountRenderViewHosts); 68}; 69 70class PopupBlockerBrowserTest : public InProcessBrowserTest { 71 public: 72 PopupBlockerBrowserTest() {} 73 74 // Returns a url that shows one popup. 75 GURL GetTestURL() { 76 return ui_test_utils::GetTestUrl( 77 base::FilePath(kTestDir), 78 base::FilePath(FILE_PATH_LITERAL("popup-blocked-to-post-blank.html"))); 79 } 80 81 std::vector<WebContents*> GetBlockedContents(Browser* browser) { 82 // Do a round trip to the renderer first to flush any in-flight IPCs to 83 // create a to-be-blocked window. 84 WebContents* tab = browser->tab_strip_model()->GetActiveWebContents(); 85 CHECK(content::ExecuteScript(tab, std::string())); 86 BlockedContentTabHelper* blocked_content_tab_helper = 87 BlockedContentTabHelper::FromWebContents(tab); 88 std::vector<WebContents*> blocked_contents; 89 blocked_content_tab_helper->GetBlockedContents(&blocked_contents); 90 return blocked_contents; 91 } 92 93 void NavigateAndCheckPopupShown(Browser* browser, const GURL& url) { 94 content::WindowedNotificationObserver observer( 95 chrome::NOTIFICATION_TAB_ADDED, 96 content::NotificationService::AllSources()); 97 ui_test_utils::NavigateToURL(browser, url); 98 observer.Wait(); 99 100 ASSERT_EQ(2u, chrome::GetBrowserCount(browser->profile(), 101 browser->host_desktop_type())); 102 103 std::vector<WebContents*> blocked_contents = GetBlockedContents(browser); 104 ASSERT_TRUE(blocked_contents.empty()); 105 } 106 107 void BasicTest(Browser* browser, const GURL& url) { 108 ui_test_utils::NavigateToURL(browser, url); 109 110 // If the popup blocker blocked the blank post, there should be only one 111 // tab in only one browser window and the URL of current tab must be equal 112 // to the original URL. 113 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 114 browser->host_desktop_type())); 115 EXPECT_EQ(1, browser->tab_strip_model()->count()); 116 WebContents* web_contents = 117 browser->tab_strip_model()->GetActiveWebContents(); 118 EXPECT_EQ(url, web_contents->GetURL()); 119 120 std::vector<WebContents*> blocked_contents = GetBlockedContents(browser); 121 ASSERT_EQ(1u, blocked_contents.size()); 122 123 content::WindowedNotificationObserver observer( 124 chrome::NOTIFICATION_TAB_ADDED, 125 content::NotificationService::AllSources()); 126 127 BlockedContentTabHelper* blocked_content_tab_helper = 128 BlockedContentTabHelper::FromWebContents(web_contents); 129 blocked_content_tab_helper->LaunchForContents(blocked_contents[0]); 130 131 observer.Wait(); 132 } 133}; 134 135IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, PopupBlockedPostBlank) { 136 BasicTest(browser(), GetTestURL()); 137} 138 139IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 140 PopupBlockedPostBlankIncognito) { 141 BasicTest(CreateIncognitoBrowser(), GetTestURL()); 142} 143 144IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 145 PopupBlockedFakeClickOnAnchor) { 146 GURL url(ui_test_utils::GetTestUrl( 147 base::FilePath(kTestDir), 148 base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor.html")))); 149 BasicTest(browser(), url); 150} 151 152IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, MultiplePopups) { 153 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 154 kTestDir), base::FilePath(FILE_PATH_LITERAL("popup-many.html")))); 155 ui_test_utils::NavigateToURL(browser(), url); 156 std::vector<WebContents*> blocked_contents = GetBlockedContents(browser()); 157 ASSERT_EQ(2u, blocked_contents.size()); 158} 159 160// Verify that popups are launched on browser back button. 161IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 162 AllowPopupThroughContentSetting) { 163 GURL url(GetTestURL()); 164 browser()->profile()->GetHostContentSettingsMap() 165 ->SetContentSetting(ContentSettingsPattern::FromURL(url), 166 ContentSettingsPattern::Wildcard(), 167 CONTENT_SETTINGS_TYPE_POPUPS, 168 std::string(), 169 CONTENT_SETTING_ALLOW); 170 171 NavigateAndCheckPopupShown(browser(), url); 172} 173 174IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, PopupsLaunchWhenTabIsClosed) { 175 CommandLine::ForCurrentProcess()->AppendSwitch( 176 switches::kDisablePopupBlocking); 177 GURL url = ui_test_utils::GetTestUrl( 178 base::FilePath(kTestDir), 179 base::FilePath(FILE_PATH_LITERAL("popup-on-unload.html"))); 180 ui_test_utils::NavigateToURL(browser(), url); 181 182 NavigateAndCheckPopupShown(browser(), GURL(content::kAboutBlankURL)); 183} 184 185// Verify that when you unblock popup, the popup shows in history and omnibox. 186IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 187 UnblockedPopupShowsInHistoryAndOmnibox) { 188 CommandLine::ForCurrentProcess()->AppendSwitch( 189 switches::kDisablePopupBlocking); 190 GURL url(GetTestURL()); 191 NavigateAndCheckPopupShown(browser(), url); 192 193 std::string search_string = 194 "data:text/html,<title>Popup Success!</title>you should not see this " 195 "message if popup blocker is enabled"; 196 197 ui_test_utils::HistoryEnumerator history(browser()->profile()); 198 std::vector<GURL>& history_urls = history.urls(); 199 ASSERT_EQ(2u, history_urls.size()); 200 ASSERT_EQ(GURL(search_string), history_urls[0]); 201 ASSERT_EQ(url, history_urls[1]); 202 203 TemplateURLService* service = TemplateURLServiceFactory::GetForProfile( 204 browser()->profile()); 205 ui_test_utils::WaitForTemplateURLServiceToLoad(service); 206 LocationBar* location_bar = browser()->window()->GetLocationBar(); 207 ui_test_utils::SendToOmniboxAndSubmit(location_bar, search_string); 208 OmniboxEditModel* model = location_bar->GetLocationEntry()->model(); 209 EXPECT_EQ(GURL(search_string), model->CurrentMatch(NULL).destination_url); 210 EXPECT_EQ(ASCIIToUTF16(search_string), model->CurrentMatch(NULL).contents); 211} 212 213IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlockWebContentsCreation) { 214 CommandLine::ForCurrentProcess()->AppendSwitch( 215 switches::kEnableBetterPopupBlocking); 216 217 CountRenderViewHosts counter; 218 219 ui_test_utils::NavigateToURL(browser(), GetTestURL()); 220 221 // If the popup blocker blocked the blank post, there should be only one tab. 222 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 223 browser()->host_desktop_type())); 224 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 225 WebContents* web_contents = 226 browser()->tab_strip_model()->GetActiveWebContents(); 227 EXPECT_EQ(GetTestURL(), web_contents->GetURL()); 228 229 // And no new RVH created. 230 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 231} 232 233IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, 234 PopupBlockedFakeClickOnAnchorNoTarget) { 235 CommandLine::ForCurrentProcess()->AppendSwitch( 236 switches::kEnableBetterPopupBlocking); 237 238 GURL url(ui_test_utils::GetTestUrl( 239 base::FilePath(kTestDir), 240 base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor2.html")))); 241 242 CountRenderViewHosts counter; 243 244 ui_test_utils::NavigateToURL(browser(), url); 245 246 // If the popup blocker blocked the blank post, there should be only one tab. 247 EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 248 browser()->host_desktop_type())); 249 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 250 WebContents* web_contents = 251 browser()->tab_strip_model()->GetActiveWebContents(); 252 EXPECT_EQ(url, web_contents->GetURL()); 253 254 // And no new RVH created. 255 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount()); 256} 257 258} // namespace 259