- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / blocked_content / popup_blocker_browsertest.cc
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/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 "testing/gtest/include/gtest/gtest.h"
38
39 using content::WebContents;
40
41 namespace {
42
43 static const base::FilePath::CharType* kTestDir =
44     FILE_PATH_LITERAL("popup_blocker");
45
46 // Counts the number of RenderViewHosts created.
47 class 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
73 class PopupBlockerBrowserTest : public InProcessBrowserTest {
74  public:
75   PopupBlockerBrowserTest() {}
76   virtual ~PopupBlockerBrowserTest() {}
77
78   int GetBlockedContentsCount() {
79     // Do a round trip to the renderer first to flush any in-flight IPCs to
80     // create a to-be-blocked window.
81     WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
82     CHECK(content::ExecuteScript(tab, std::string()));
83     PopupBlockerTabHelper* popup_blocker_helper =
84         PopupBlockerTabHelper::FromWebContents(tab);
85     return popup_blocker_helper->GetBlockedPopupsCount();
86   }
87
88   void NavigateAndCheckPopupShown(const GURL& url) {
89     content::WindowedNotificationObserver observer(
90         chrome::NOTIFICATION_TAB_ADDED,
91         content::NotificationService::AllSources());
92     ui_test_utils::NavigateToURL(browser(), url);
93     observer.Wait();
94
95     ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
96                                           browser()->host_desktop_type()));
97
98     ASSERT_EQ(0, GetBlockedContentsCount());
99   }
100
101   // Navigates to the test indicated by |test_name| using |browser| which is
102   // expected to try to open a popup. Verifies that the popup was blocked and
103   // then opens the blocked popup. Once the popup stopped loading, verifies
104   // that the title of the page is "PASS" if |check_title| is true.
105   //
106   // If |expect_new_browser| is true, the popup is expected to open a new
107   // window, or a background tab if it is false.
108   //
109   // Returns the WebContents of the launched popup.
110   WebContents* RunCheckTest(Browser* browser,
111                             const base::FilePath& test_name,
112                             bool expect_new_browser,
113                             bool check_title) {
114     GURL url(ui_test_utils::GetTestUrl(base::FilePath(kTestDir), test_name));
115
116     CountRenderViewHosts counter;
117
118     ui_test_utils::NavigateToURL(browser, url);
119
120     // Since the popup blocker blocked the window.open, there should be only one
121     // tab.
122     EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(),
123                                           browser->host_desktop_type()));
124     EXPECT_EQ(1, browser->tab_strip_model()->count());
125     WebContents* web_contents =
126         browser->tab_strip_model()->GetActiveWebContents();
127     EXPECT_EQ(url, web_contents->GetURL());
128
129     // And no new RVH created.
130     EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount());
131
132     content::WindowedNotificationObserver observer(
133         chrome::NOTIFICATION_TAB_ADDED,
134         content::NotificationService::AllSources());
135     ui_test_utils::BrowserAddedObserver browser_observer;
136
137     // Launch the blocked popup.
138     PopupBlockerTabHelper* popup_blocker_helper =
139         PopupBlockerTabHelper::FromWebContents(web_contents);
140     if (!popup_blocker_helper->GetBlockedPopupsCount()) {
141       content::WindowedNotificationObserver observer(
142           chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
143           content::NotificationService::AllSources());
144       observer.Wait();
145     }
146     EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount());
147     std::map<int32, GURL> blocked_requests =
148         popup_blocker_helper->GetBlockedPopupRequests();
149     std::map<int32, GURL>::const_iterator iter = blocked_requests.begin();
150     popup_blocker_helper->ShowBlockedPopup(iter->first);
151
152     observer.Wait();
153     Browser* new_browser;
154     if (expect_new_browser) {
155       new_browser = browser_observer.WaitForSingleNewBrowser();
156       web_contents = new_browser->tab_strip_model()->GetActiveWebContents();
157     } else {
158       new_browser = browser;
159       EXPECT_EQ(2, browser->tab_strip_model()->count());
160       web_contents = browser->tab_strip_model()->GetWebContentsAt(1);
161     }
162
163     if (check_title) {
164       // Check that the check passed.
165       base::string16 expected_title(base::ASCIIToUTF16("PASS"));
166       content::TitleWatcher title_watcher(web_contents, expected_title);
167       EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
168     }
169
170     return web_contents;
171   }
172
173  private:
174   DISALLOW_COPY_AND_ASSIGN(PopupBlockerBrowserTest);
175 };
176
177 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
178                        BlockWebContentsCreation) {
179 #if defined(OS_WIN) && defined(USE_ASH)
180   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
181   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
182     return;
183 #endif
184
185   RunCheckTest(
186       browser(),
187       base::FilePath(FILE_PATH_LITERAL("popup-blocked-to-post-blank.html")),
188       true,
189       false);
190 }
191
192 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
193                        BlockWebContentsCreationIncognito) {
194 #if defined(OS_WIN) && defined(USE_ASH)
195   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
196   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
197     return;
198 #endif
199
200   RunCheckTest(
201       CreateIncognitoBrowser(),
202       base::FilePath(FILE_PATH_LITERAL("popup-blocked-to-post-blank.html")),
203       true,
204       false);
205 }
206
207 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
208                        PopupBlockedFakeClickOnAnchor) {
209 #if defined(OS_WIN) && defined(USE_ASH)
210   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
211   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
212     return;
213 #endif
214
215   RunCheckTest(
216       browser(),
217       base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor.html")),
218       false,
219       false);
220 }
221
222 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
223                        PopupBlockedFakeClickOnAnchorNoTarget) {
224 #if defined(OS_WIN) && defined(USE_ASH)
225   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
226   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
227     return;
228 #endif
229
230   RunCheckTest(
231       browser(),
232       base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor2.html")),
233       false,
234       false);
235 }
236
237 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, MultiplePopups) {
238   GURL url(ui_test_utils::GetTestUrl(
239       base::FilePath(kTestDir),
240       base::FilePath(FILE_PATH_LITERAL("popup-many.html"))));
241   ui_test_utils::NavigateToURL(browser(), url);
242   ASSERT_EQ(2, GetBlockedContentsCount());
243 }
244
245 // Verify that popups are launched on browser back button.
246 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
247                        AllowPopupThroughContentSetting) {
248   GURL url(ui_test_utils::GetTestUrl(
249       base::FilePath(kTestDir),
250       base::FilePath(FILE_PATH_LITERAL("popup-blocked-to-post-blank.html"))));
251   browser()->profile()->GetHostContentSettingsMap()
252       ->SetContentSetting(ContentSettingsPattern::FromURL(url),
253                           ContentSettingsPattern::Wildcard(),
254                           CONTENT_SETTINGS_TYPE_POPUPS,
255                           std::string(),
256                           CONTENT_SETTING_ALLOW);
257
258   NavigateAndCheckPopupShown(url);
259 }
260
261 // Verify that content settings are applied based on the top-level frame URL.
262 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
263                        AllowPopupThroughContentSettingIFrame) {
264   GURL url(ui_test_utils::GetTestUrl(
265       base::FilePath(kTestDir),
266       base::FilePath(FILE_PATH_LITERAL("popup-frames.html"))));
267   browser()->profile()->GetHostContentSettingsMap()
268       ->SetContentSetting(ContentSettingsPattern::FromURL(url),
269                           ContentSettingsPattern::Wildcard(),
270                           CONTENT_SETTINGS_TYPE_POPUPS,
271                           std::string(),
272                           CONTENT_SETTING_ALLOW);
273
274   // Popup from the iframe should be allowed since the top-level URL is
275   // whitelisted.
276   NavigateAndCheckPopupShown(url);
277
278   // Whitelist iframe URL instead.
279   GURL frame_url(ui_test_utils::GetTestUrl(
280       base::FilePath(kTestDir),
281       base::FilePath(FILE_PATH_LITERAL("popup-frames-iframe.html"))));
282   browser()->profile()->GetHostContentSettingsMap()->ClearSettingsForOneType(
283       CONTENT_SETTINGS_TYPE_POPUPS);
284   browser()->profile()->GetHostContentSettingsMap()
285       ->SetContentSetting(ContentSettingsPattern::FromURL(frame_url),
286                           ContentSettingsPattern::Wildcard(),
287                           CONTENT_SETTINGS_TYPE_POPUPS,
288                           std::string(),
289                           CONTENT_SETTING_ALLOW);
290
291   // Popup should be blocked.
292   ui_test_utils::NavigateToURL(browser(), url);
293   ASSERT_EQ(1, GetBlockedContentsCount());
294 }
295
296 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
297                        PopupsLaunchWhenTabIsClosed) {
298   CommandLine::ForCurrentProcess()->AppendSwitch(
299       switches::kDisablePopupBlocking);
300   GURL url = ui_test_utils::GetTestUrl(
301       base::FilePath(kTestDir),
302       base::FilePath(FILE_PATH_LITERAL("popup-on-unload.html")));
303   ui_test_utils::NavigateToURL(browser(), url);
304
305   NavigateAndCheckPopupShown(GURL(content::kAboutBlankURL));
306 }
307
308 // Verify that when you unblock popup, the popup shows in history and omnibox.
309 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
310                        UnblockedPopupShowsInHistoryAndOmnibox) {
311   CommandLine::ForCurrentProcess()->AppendSwitch(
312       switches::kDisablePopupBlocking);
313   GURL url(ui_test_utils::GetTestUrl(
314       base::FilePath(kTestDir),
315       base::FilePath(FILE_PATH_LITERAL("popup-blocked-to-post-blank.html"))));
316   NavigateAndCheckPopupShown(url);
317
318   std::string search_string =
319       "data:text/html,<title>Popup Success!</title>you should not see this "
320       "message if popup blocker is enabled";
321
322   ui_test_utils::HistoryEnumerator history(browser()->profile());
323   std::vector<GURL>& history_urls = history.urls();
324   ASSERT_EQ(2u, history_urls.size());
325   ASSERT_EQ(GURL(search_string), history_urls[0]);
326   ASSERT_EQ(url, history_urls[1]);
327
328   TemplateURLService* service = TemplateURLServiceFactory::GetForProfile(
329       browser()->profile());
330   ui_test_utils::WaitForTemplateURLServiceToLoad(service);
331   LocationBar* location_bar = browser()->window()->GetLocationBar();
332   ui_test_utils::SendToOmniboxAndSubmit(location_bar, search_string);
333   OmniboxEditModel* model = location_bar->GetLocationEntry()->model();
334   EXPECT_EQ(GURL(search_string), model->CurrentMatch(NULL).destination_url);
335   EXPECT_EQ(ASCIIToUTF16(search_string), model->CurrentMatch(NULL).contents);
336 }
337
338 // This test fails on linux AURA with this change
339 // https://codereview.chromium.org/23903056
340 // BUG=https://code.google.com/p/chromium/issues/detail?id=295299
341 // TODO(ananta). Debug and fix this test.
342 #if defined(USE_AURA) && defined(OS_LINUX)
343 #define MAYBE_WindowFeatures DISABLED_WindowFeatures
344 #else
345 #define MAYBE_WindowFeatures WindowFeatures
346 #endif
347 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, MAYBE_WindowFeatures) {
348   WebContents* popup =
349       RunCheckTest(browser(),
350                    base::FilePath(FILE_PATH_LITERAL("popup-window-open.html")),
351                    true,
352                    false);
353
354   // Check that the new popup has (roughly) the requested size.
355   gfx::Size window_size = popup->GetView()->GetContainerSize();
356   EXPECT_TRUE(349 <= window_size.width() && window_size.width() <= 351);
357   EXPECT_TRUE(249 <= window_size.height() && window_size.height() <= 251);
358 }
359
360 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, CorrectReferrer) {
361   RunCheckTest(browser(),
362                base::FilePath(FILE_PATH_LITERAL("popup-referrer.html")),
363                true,
364                true);
365 }
366
367 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, WindowFeaturesBarProps) {
368   RunCheckTest(browser(),
369                base::FilePath(FILE_PATH_LITERAL("popup-windowfeatures.html")),
370                true,
371                true);
372 }
373
374 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, SessionStorage) {
375   RunCheckTest(browser(),
376                base::FilePath(FILE_PATH_LITERAL("popup-sessionstorage.html")),
377                true,
378                true);
379 }
380
381 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, Opener) {
382   RunCheckTest(browser(),
383                base::FilePath(FILE_PATH_LITERAL("popup-opener.html")),
384                true,
385                true);
386 }
387
388 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, OpenerSuppressed) {
389   RunCheckTest(browser(),
390                base::FilePath(FILE_PATH_LITERAL("popup-openersuppressed.html")),
391                false,
392                true);
393 }
394
395 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, ShiftClick) {
396   RunCheckTest(
397       browser(),
398       base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor3.html")),
399       true,
400       true);
401 }
402
403 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, WebUI) {
404   WebContents* popup =
405       RunCheckTest(browser(),
406                    base::FilePath(FILE_PATH_LITERAL("popup-webui.html")),
407                    true,
408                    false);
409
410   // Check that the new popup displays about:blank.
411   EXPECT_EQ(GURL(content::kAboutBlankURL), popup->GetURL());
412 }
413
414 // Verify that the renderer can't DOS the browser by creating arbitrarily many
415 // popups.
416 IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, DenialOfService) {
417   GURL url(ui_test_utils::GetTestUrl(
418       base::FilePath(kTestDir),
419       base::FilePath(FILE_PATH_LITERAL("popup-dos.html"))));
420   ui_test_utils::NavigateToURL(browser(), url);
421   ASSERT_EQ(25, GetBlockedContentsCount());
422 }
423
424 }  // namespace