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