Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / blocked_content / popup_blocker_browsertest.cc
blobecf15ddabd562e52f66ca943b689d8a8ef3bd419
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.
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/popup_blocker_tab_helper.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_commands.h"
20 #include "chrome/browser/ui/browser_finder.h"
21 #include "chrome/browser/ui/browser_window.h"
22 #include "chrome/browser/ui/omnibox/location_bar.h"
23 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
24 #include "chrome/browser/ui/omnibox/omnibox_view.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/test/base/in_process_browser_test.h"
29 #include "chrome/test/base/test_switches.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 "net/dns/mock_host_resolver.h"
38 #include "net/test/embedded_test_server/embedded_test_server.h"
39 #include "testing/gtest/include/gtest/gtest.h"
41 using content::WebContents;
43 namespace {
45 // Counts the number of RenderViewHosts created.
46 class CountRenderViewHosts : public content::NotificationObserver {
47 public:
48 CountRenderViewHosts()
49 : count_(0) {
50 registrar_.Add(this,
51 content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
52 content::NotificationService::AllSources());
54 virtual ~CountRenderViewHosts() {}
56 int GetRenderViewHostCreatedCount() const { return count_; }
58 private:
59 virtual void Observe(int type,
60 const content::NotificationSource& source,
61 const content::NotificationDetails& details) OVERRIDE {
62 count_++;
65 content::NotificationRegistrar registrar_;
67 int count_;
69 DISALLOW_COPY_AND_ASSIGN(CountRenderViewHosts);
72 class PopupBlockerBrowserTest : public InProcessBrowserTest {
73 public:
74 PopupBlockerBrowserTest() {}
75 virtual ~PopupBlockerBrowserTest() {}
77 virtual void SetUpOnMainThread() OVERRIDE {
78 InProcessBrowserTest::SetUpOnMainThread();
80 host_resolver()->AddRule("*", "127.0.0.1");
81 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
84 int GetBlockedContentsCount() {
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 PopupBlockerTabHelper* popup_blocker_helper =
90 PopupBlockerTabHelper::FromWebContents(tab);
91 return popup_blocker_helper->GetBlockedPopupsCount();
94 void NavigateAndCheckPopupShown(const GURL& url) {
95 content::WindowedNotificationObserver observer(
96 chrome::NOTIFICATION_TAB_ADDED,
97 content::NotificationService::AllSources());
98 ui_test_utils::NavigateToURL(browser(), url);
99 observer.Wait();
101 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
102 browser()->host_desktop_type()));
104 ASSERT_EQ(0, GetBlockedContentsCount());
107 // Navigates to the test indicated by |test_name| using |browser| which is
108 // expected to try to open a popup. Verifies that the popup was blocked and
109 // then opens the blocked popup. Once the popup stopped loading, verifies
110 // that the title of the page is "PASS" if |check_title| is true.
112 // If |expect_new_browser| is true, the popup is expected to open a new
113 // window, or a background tab if it is false.
115 // Returns the WebContents of the launched popup.
116 WebContents* RunCheckTest(Browser* browser,
117 const std::string& test_name,
118 bool expect_new_browser,
119 bool check_title) {
120 GURL url(embedded_test_server()->GetURL(test_name));
122 CountRenderViewHosts counter;
124 ui_test_utils::NavigateToURL(browser, url);
126 // Since the popup blocker blocked the window.open, there should be only one
127 // tab.
128 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(),
129 browser->host_desktop_type()));
130 EXPECT_EQ(1, browser->tab_strip_model()->count());
131 WebContents* web_contents =
132 browser->tab_strip_model()->GetActiveWebContents();
133 EXPECT_EQ(url, web_contents->GetURL());
135 // And no new RVH created.
136 EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount());
138 content::WindowedNotificationObserver observer(
139 chrome::NOTIFICATION_TAB_ADDED,
140 content::NotificationService::AllSources());
141 ui_test_utils::BrowserAddedObserver browser_observer;
143 // Launch the blocked popup.
144 PopupBlockerTabHelper* popup_blocker_helper =
145 PopupBlockerTabHelper::FromWebContents(web_contents);
146 if (!popup_blocker_helper->GetBlockedPopupsCount()) {
147 content::WindowedNotificationObserver observer(
148 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
149 content::NotificationService::AllSources());
150 observer.Wait();
152 EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount());
153 std::map<int32, GURL> blocked_requests =
154 popup_blocker_helper->GetBlockedPopupRequests();
155 std::map<int32, GURL>::const_iterator iter = blocked_requests.begin();
156 popup_blocker_helper->ShowBlockedPopup(iter->first);
158 observer.Wait();
159 Browser* new_browser;
160 if (expect_new_browser) {
161 new_browser = browser_observer.WaitForSingleNewBrowser();
162 web_contents = new_browser->tab_strip_model()->GetActiveWebContents();
163 } else {
164 new_browser = browser;
165 EXPECT_EQ(2, browser->tab_strip_model()->count());
166 web_contents = browser->tab_strip_model()->GetWebContentsAt(1);
169 if (check_title) {
170 // Check that the check passed.
171 base::string16 expected_title(base::ASCIIToUTF16("PASS"));
172 content::TitleWatcher title_watcher(web_contents, expected_title);
173 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
176 return web_contents;
179 private:
180 DISALLOW_COPY_AND_ASSIGN(PopupBlockerBrowserTest);
183 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
184 BlockWebContentsCreation) {
185 #if defined(OS_WIN) && defined(USE_ASH)
186 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
187 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
188 return;
189 #endif
191 RunCheckTest(
192 browser(),
193 "/popup_blocker/popup-blocked-to-post-blank.html",
194 true,
195 false);
198 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
199 BlockWebContentsCreationIncognito) {
200 #if defined(OS_WIN) && defined(USE_ASH)
201 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
202 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
203 return;
204 #endif
206 RunCheckTest(
207 CreateIncognitoBrowser(),
208 "/popup_blocker/popup-blocked-to-post-blank.html",
209 true,
210 false);
213 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
214 PopupBlockedFakeClickOnAnchor) {
215 #if defined(OS_WIN) && defined(USE_ASH)
216 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
217 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
218 return;
219 #endif
221 RunCheckTest(
222 browser(),
223 "/popup_blocker/popup-fake-click-on-anchor.html",
224 false,
225 false);
228 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
229 PopupBlockedFakeClickOnAnchorNoTarget) {
230 #if defined(OS_WIN) && defined(USE_ASH)
231 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
232 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
233 return;
234 #endif
236 RunCheckTest(
237 browser(),
238 "/popup_blocker/popup-fake-click-on-anchor2.html",
239 false,
240 false);
243 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, MultiplePopups) {
244 GURL url(embedded_test_server()->GetURL("/popup_blocker/popup-many.html"));
245 ui_test_utils::NavigateToURL(browser(), url);
246 ASSERT_EQ(2, GetBlockedContentsCount());
249 // Verify that popups are launched on browser back button.
250 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
251 AllowPopupThroughContentSetting) {
252 GURL url(embedded_test_server()->GetURL(
253 "/popup_blocker/popup-blocked-to-post-blank.html"));
254 browser()->profile()->GetHostContentSettingsMap()
255 ->SetContentSetting(ContentSettingsPattern::FromURL(url),
256 ContentSettingsPattern::Wildcard(),
257 CONTENT_SETTINGS_TYPE_POPUPS,
258 std::string(),
259 CONTENT_SETTING_ALLOW);
261 NavigateAndCheckPopupShown(url);
264 // Verify that content settings are applied based on the top-level frame URL.
265 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
266 AllowPopupThroughContentSettingIFrame) {
267 GURL url(embedded_test_server()->GetURL("/popup_blocker/popup-frames.html"));
268 browser()->profile()->GetHostContentSettingsMap()
269 ->SetContentSetting(ContentSettingsPattern::FromURL(url),
270 ContentSettingsPattern::Wildcard(),
271 CONTENT_SETTINGS_TYPE_POPUPS,
272 std::string(),
273 CONTENT_SETTING_ALLOW);
275 // Popup from the iframe should be allowed since the top-level URL is
276 // whitelisted.
277 NavigateAndCheckPopupShown(url);
279 // Whitelist iframe URL instead.
280 GURL::Replacements replace_host;
281 std::string host_str("www.a.com"); // Must stay in scope with replace_host
282 replace_host.SetHostStr(host_str);
283 GURL frame_url(embedded_test_server()
284 ->GetURL("/popup_blocker/popup-frames-iframe.html")
285 .ReplaceComponents(replace_host));
286 browser()->profile()->GetHostContentSettingsMap()->ClearSettingsForOneType(
287 CONTENT_SETTINGS_TYPE_POPUPS);
288 browser()->profile()->GetHostContentSettingsMap()
289 ->SetContentSetting(ContentSettingsPattern::FromURL(frame_url),
290 ContentSettingsPattern::Wildcard(),
291 CONTENT_SETTINGS_TYPE_POPUPS,
292 std::string(),
293 CONTENT_SETTING_ALLOW);
295 // Popup should be blocked.
296 ui_test_utils::NavigateToURL(browser(), url);
297 ASSERT_EQ(1, GetBlockedContentsCount());
300 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
301 PopupsLaunchWhenTabIsClosed) {
302 CommandLine::ForCurrentProcess()->AppendSwitch(
303 switches::kDisablePopupBlocking);
304 GURL url(
305 embedded_test_server()->GetURL("/popup_blocker/popup-on-unload.html"));
306 ui_test_utils::NavigateToURL(browser(), url);
308 NavigateAndCheckPopupShown(embedded_test_server()->GetURL("/popup_blocker/"));
311 // Verify that when you unblock popup, the popup shows in history and omnibox.
312 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
313 UnblockedPopupShowsInHistoryAndOmnibox) {
314 CommandLine::ForCurrentProcess()->AppendSwitch(
315 switches::kDisablePopupBlocking);
316 GURL url(embedded_test_server()->GetURL(
317 "/popup_blocker/popup-blocked-to-post-blank.html"));
318 NavigateAndCheckPopupShown(url);
320 std::string search_string =
321 "data:text/html,<title>Popup Success!</title>you should not see this "
322 "message if popup blocker is enabled";
324 ui_test_utils::HistoryEnumerator history(browser()->profile());
325 std::vector<GURL>& history_urls = history.urls();
326 ASSERT_EQ(2u, history_urls.size());
327 ASSERT_EQ(GURL(search_string), history_urls[0]);
328 ASSERT_EQ(url, history_urls[1]);
330 TemplateURLService* service = TemplateURLServiceFactory::GetForProfile(
331 browser()->profile());
332 ui_test_utils::WaitForTemplateURLServiceToLoad(service);
333 LocationBar* location_bar = browser()->window()->GetLocationBar();
334 ui_test_utils::SendToOmniboxAndSubmit(location_bar, search_string);
335 OmniboxEditModel* model = location_bar->GetOmniboxView()->model();
336 EXPECT_EQ(GURL(search_string), model->CurrentMatch(NULL).destination_url);
337 EXPECT_EQ(base::ASCIIToUTF16(search_string),
338 model->CurrentMatch(NULL).contents);
341 // This test fails on linux AURA with this change
342 // https://codereview.chromium.org/23903056
343 // BUG=https://code.google.com/p/chromium/issues/detail?id=295299
344 // TODO(ananta). Debug and fix this test.
345 #if defined(USE_AURA) && defined(OS_LINUX)
346 #define MAYBE_WindowFeatures DISABLED_WindowFeatures
347 #else
348 #define MAYBE_WindowFeatures WindowFeatures
349 #endif
350 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, MAYBE_WindowFeatures) {
351 WebContents* popup =
352 RunCheckTest(browser(),
353 "/popup_blocker/popup-window-open.html",
354 true,
355 false);
357 // Check that the new popup has (roughly) the requested size.
358 gfx::Size window_size = popup->GetView()->GetContainerSize();
359 EXPECT_TRUE(349 <= window_size.width() && window_size.width() <= 351);
360 EXPECT_TRUE(249 <= window_size.height() && window_size.height() <= 251);
363 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, CorrectReferrer) {
364 RunCheckTest(browser(),
365 "/popup_blocker/popup-referrer.html",
366 true,
367 true);
370 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, WindowFeaturesBarProps) {
371 RunCheckTest(browser(),
372 "/popup_blocker/popup-windowfeatures.html",
373 true,
374 true);
377 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, SessionStorage) {
378 RunCheckTest(browser(),
379 "/popup_blocker/popup-sessionstorage.html",
380 true,
381 true);
384 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, Opener) {
385 RunCheckTest(browser(),
386 "/popup_blocker/popup-opener.html",
387 true,
388 true);
391 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, OpenerSuppressed) {
392 RunCheckTest(browser(),
393 "/popup_blocker/popup-openersuppressed.html",
394 false,
395 true);
398 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, ShiftClick) {
399 RunCheckTest(
400 browser(),
401 "/popup_blocker/popup-fake-click-on-anchor3.html",
402 true,
403 true);
406 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, WebUI) {
407 WebContents* popup =
408 RunCheckTest(browser(),
409 "/popup_blocker/popup-webui.html",
410 true,
411 false);
413 // Check that the new popup displays about:blank.
414 EXPECT_EQ(GURL(content::kAboutBlankURL), popup->GetURL());
417 // Verify that the renderer can't DOS the browser by creating arbitrarily many
418 // popups.
419 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, DenialOfService) {
420 GURL url(embedded_test_server()->GetURL("/popup_blocker/popup-dos.html"));
421 ui_test_utils::NavigateToURL(browser(), url);
422 ASSERT_EQ(25, GetBlockedContentsCount());
425 } // namespace