diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/weblayer/browser/popup_blocker_browsertest.cc | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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.cc | 265 |
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 |