summaryrefslogtreecommitdiff
path: root/chromium/weblayer/browser/popup_blocker_browsertest.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/weblayer/browser/popup_blocker_browsertest.cc
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/weblayer/browser/popup_blocker_browsertest.cc')
-rw-r--r--chromium/weblayer/browser/popup_blocker_browsertest.cc265
1 files changed, 265 insertions, 0 deletions
diff --git a/chromium/weblayer/browser/popup_blocker_browsertest.cc b/chromium/weblayer/browser/popup_blocker_browsertest.cc
new file mode 100644
index 00000000000..bd53f10dda5
--- /dev/null
+++ b/chromium/weblayer/browser/popup_blocker_browsertest.cc
@@ -0,0 +1,265 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "build/build_config.h"
+#include "components/blocked_content/popup_blocker_tab_helper.h"
+#include "ui/base/page_transition_types.h"
+#include "ui/base/window_open_disposition.h"
+#include "weblayer/browser/browser_impl.h"
+#include "weblayer/browser/host_content_settings_map_factory.h"
+#include "weblayer/browser/profile_impl.h"
+#include "weblayer/browser/tab_impl.h"
+#include "weblayer/public/browser.h"
+#include "weblayer/public/browser_observer.h"
+#include "weblayer/public/navigation_controller.h"
+#include "weblayer/public/new_tab_delegate.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/test_navigation_observer.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+namespace weblayer {
+
+class PopupBlockerBrowserTest : public WebLayerBrowserTest,
+ public NewTabDelegate,
+ public BrowserObserver {
+ public:
+ // WebLayerBrowserTest:
+ void SetUpOnMainThread() override {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ original_tab_ = shell()->tab();
+#if !defined(OS_ANDROID)
+ // Android does this in Java.
+ original_tab_->SetNewTabDelegate(this);
+#endif
+ shell()->browser()->AddObserver(this);
+
+ NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"),
+ original_tab_);
+ }
+ void TearDownOnMainThread() override {
+ shell()->browser()->RemoveObserver(this);
+ }
+
+ // NewTabDelegate:
+ void OnNewTab(Tab* new_tab, NewTabType type) override {}
+ void CloseTab() override {}
+
+ // BrowserObserver:
+ void OnTabAdded(Tab* tab) override {
+ new_tab_ = tab;
+ if (new_tab_run_loop_)
+ new_tab_run_loop_->Quit();
+ }
+ void OnTabRemoved(Tab* tab, bool active_tab_changed) override {
+ ASSERT_EQ(tab, new_tab_);
+ new_tab_ = nullptr;
+ if (close_tab_run_loop_)
+ close_tab_run_loop_->Quit();
+ }
+
+ size_t GetBlockedPopupCount() {
+ return blocked_content::PopupBlockerTabHelper::FromWebContents(
+ GetWebContents(original_tab_))
+ ->GetBlockedPopupsCount();
+ }
+
+ content::WebContents* GetWebContents(Tab* tab) {
+ return static_cast<TabImpl*>(tab)->web_contents();
+ }
+
+ Tab* WaitForNewTab() {
+ if (!new_tab_) {
+ new_tab_run_loop_ = std::make_unique<base::RunLoop>();
+ new_tab_run_loop_->Run();
+ new_tab_run_loop_ = nullptr;
+ }
+ return new_tab_;
+ }
+
+ void WaitForCloseTab() {
+ if (new_tab_) {
+ close_tab_run_loop_ = std::make_unique<base::RunLoop>();
+ close_tab_run_loop_->Run();
+ close_tab_run_loop_ = nullptr;
+ }
+ ASSERT_FALSE(new_tab_);
+ }
+
+ void ExpectTabURL(Tab* tab, const GURL& url) {
+ if (tab->GetNavigationController()->GetNavigationListSize() > 0) {
+ EXPECT_EQ(tab->GetNavigationController()->GetNavigationEntryDisplayURL(0),
+ url);
+ } else {
+ TestNavigationObserver(
+ url, TestNavigationObserver::NavigationEvent::kCompletion, tab)
+ .Wait();
+ }
+ }
+
+ Tab* ShowPopup(const GURL& url) {
+ auto* popup_blocker =
+ blocked_content::PopupBlockerTabHelper::FromWebContents(
+ GetWebContents(original_tab_));
+ popup_blocker->ShowBlockedPopup(
+ popup_blocker->GetBlockedPopupRequests().begin()->first,
+ WindowOpenDisposition::NEW_FOREGROUND_TAB);
+ Tab* new_tab = WaitForNewTab();
+ ExpectTabURL(new_tab, url);
+ EXPECT_EQ(GetBlockedPopupCount(), 0u);
+ return new_tab;
+ }
+
+ Tab* original_tab() { return original_tab_; }
+
+ private:
+ std::unique_ptr<base::RunLoop> new_tab_run_loop_;
+ std::unique_ptr<base::RunLoop> close_tab_run_loop_;
+
+ Tab* original_tab_ = nullptr;
+ Tab* new_tab_ = nullptr;
+};
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlocksPopup) {
+ ExecuteScript(original_tab(), "window.open('https://google.com')", true);
+ EXPECT_EQ(GetBlockedPopupCount(), 1u);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlocksMultiplePopups) {
+ ExecuteScript(original_tab(), "window.open('https://google.com')", true);
+ ExecuteScript(original_tab(), "window.open('https://google.com')", true);
+ EXPECT_EQ(GetBlockedPopupCount(), 2u);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, DoesNotBlockUserGesture) {
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ ExecuteScriptWithUserGesture(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()));
+
+ Tab* new_tab = WaitForNewTab();
+ ExpectTabURL(new_tab, popup_url);
+ EXPECT_EQ(GetBlockedPopupCount(), 0u);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, OpensBlockedPopup) {
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ ExecuteScript(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
+ EXPECT_EQ(GetBlockedPopupCount(), 1u);
+
+ Tab* new_tab = ShowPopup(popup_url);
+
+ // Blocked popups should no longer have the opener set to match Chrome
+ // behavior.
+ EXPECT_FALSE(GetWebContents(new_tab)->HasOpener());
+ // Make sure we can cleanly close the popup, and there's no crash.
+ ExecuteScriptWithUserGesture(new_tab, "window.close()");
+ WaitForCloseTab();
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+ AllowsPopupThroughContentSettingException) {
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ HostContentSettingsMapFactory::GetForBrowserContext(
+ GetWebContents(original_tab())->GetBrowserContext())
+ ->SetContentSettingDefaultScope(popup_url, GURL(),
+ ContentSettingsType::POPUPS,
+ std::string(), CONTENT_SETTING_ALLOW);
+ ExecuteScript(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
+ Tab* new_tab = WaitForNewTab();
+ ExpectTabURL(new_tab, popup_url);
+ EXPECT_EQ(GetBlockedPopupCount(), 0u);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+ AllowsPopupThroughContentSettingDefaultValue) {
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ HostContentSettingsMapFactory::GetForBrowserContext(
+ GetWebContents(original_tab())->GetBrowserContext())
+ ->SetDefaultContentSetting(ContentSettingsType::POPUPS,
+ CONTENT_SETTING_ALLOW);
+ ExecuteScript(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
+ Tab* new_tab = WaitForNewTab();
+ ExpectTabURL(new_tab, popup_url);
+ EXPECT_EQ(GetBlockedPopupCount(), 0u);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+ BlockPopupThroughContentSettingException) {
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ HostContentSettingsMapFactory::GetForBrowserContext(
+ GetWebContents(original_tab())->GetBrowserContext())
+ ->SetDefaultContentSetting(ContentSettingsType::POPUPS,
+ CONTENT_SETTING_ALLOW);
+ HostContentSettingsMapFactory::GetForBrowserContext(
+ GetWebContents(original_tab())->GetBrowserContext())
+ ->SetContentSettingDefaultScope(popup_url, GURL(),
+ ContentSettingsType::POPUPS,
+ std::string(), CONTENT_SETTING_BLOCK);
+ ExecuteScript(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
+ EXPECT_EQ(GetBlockedPopupCount(), 1u);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+ BlocksAndOpensPopupFromOpenURL) {
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ content::OpenURLParams params(popup_url, content::Referrer(),
+ WindowOpenDisposition::NEW_FOREGROUND_TAB,
+ ui::PAGE_TRANSITION_LINK, true);
+ params.initiator_origin = url::Origin::Create(popup_url);
+ GetWebContents(original_tab())->OpenURL(params);
+ EXPECT_EQ(GetBlockedPopupCount(), 1u);
+
+ ShowPopup(popup_url);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+ DoesNotOpenPopupWithoutNewTabDelegate) {
+ NewTabDelegate* old_delegate =
+ static_cast<TabImpl*>(original_tab())->new_tab_delegate();
+ original_tab()->SetNewTabDelegate(nullptr);
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ ExecuteScriptWithUserGesture(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()));
+ EXPECT_EQ(GetBlockedPopupCount(), 0u);
+
+ // Navigate the original tab, then make sure we still only have a single tab.
+ NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"),
+ original_tab());
+ EXPECT_EQ(shell()->browser()->GetTabs().size(), 1u);
+
+ // Restore the old delegate to make sure it is cleaned up on Android.
+ original_tab()->SetNewTabDelegate(old_delegate);
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+ DoesNotOpenBlockedPopupWithoutNewTabDelegate) {
+ NewTabDelegate* old_delegate =
+ static_cast<TabImpl*>(original_tab())->new_tab_delegate();
+ original_tab()->SetNewTabDelegate(nullptr);
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ ExecuteScript(
+ original_tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
+ EXPECT_EQ(GetBlockedPopupCount(), 0u);
+
+ // Navigate the original tab, then make sure we still only have a single tab.
+ NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"),
+ original_tab());
+ EXPECT_EQ(shell()->browser()->GetTabs().size(), 1u);
+
+ // Restore the old delegate to make sure it is cleaned up on Android.
+ original_tab()->SetNewTabDelegate(old_delegate);
+}
+
+} // namespace weblayer