ad_density_intervention_browsertest.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright 2021 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. #include <memory>
  5. #include "base/test/scoped_feature_list.h"
  6. #include "components/infobars/content/content_infobar_manager.h"
  7. #include "components/infobars/core/infobar.h"
  8. #include "components/infobars/core/infobar_delegate.h"
  9. #include "components/infobars/core/infobar_manager.h"
  10. #include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h"
  11. #include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
  12. #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
  13. #include "components/subresource_filter/core/browser/subresource_filter_features.h"
  14. #include "components/subresource_filter/core/common/common_features.h"
  15. #include "components/subresource_filter/core/common/test_ruleset_utils.h"
  16. #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h"
  17. #include "components/ukm/test_ukm_recorder.h"
  18. #include "content/public/test/browser_test.h"
  19. #include "content/public/test/browser_test_utils.h"
  20. #include "net/test/embedded_test_server/embedded_test_server.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. #include "ui/display/screen_info.h"
  23. #include "ui/gfx/geometry/rect.h"
  24. #include "url/gurl.h"
  25. #include "weblayer/test/subresource_filter_browser_test_harness.h"
  26. namespace weblayer {
  27. namespace {
  28. const char kAdsInterventionRecordedHistogram[] =
  29. "SubresourceFilter.PageLoad.AdsInterventionTriggered";
  30. } // namespace
  31. class AdDensityViolationBrowserTest : public SubresourceFilterBrowserTest {
  32. public:
  33. AdDensityViolationBrowserTest() = default;
  34. void SetUp() override {
  35. std::vector<base::Feature> enabled = {
  36. subresource_filter::kAdTagging,
  37. subresource_filter::kAdsInterventionsEnforced};
  38. std::vector<base::Feature> disabled = {};
  39. feature_list_.InitWithFeatures(enabled, disabled);
  40. SubresourceFilterBrowserTest::SetUp();
  41. }
  42. void SetUpOnMainThread() override {
  43. SubresourceFilterBrowserTest::SetUpOnMainThread();
  44. SetRulesetWithRules(
  45. {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")});
  46. }
  47. private:
  48. base::test::ScopedFeatureList feature_list_;
  49. };
  50. IN_PROC_BROWSER_TEST_F(
  51. AdDensityViolationBrowserTest,
  52. MobilePageAdDensityByHeightAbove30_AdInterventionTriggered) {
  53. base::HistogramTester histogram_tester;
  54. ukm::TestAutoSetUkmRecorder ukm_recorder;
  55. auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
  56. web_contents());
  57. const GURL url(embedded_test_server()->GetURL(
  58. "a.com", "/ads_observer/blank_with_adiframe_writer.html"));
  59. waiter->SetMainFrameIntersectionExpectation();
  60. EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
  61. waiter->Wait();
  62. int document_height = page_load_metrics::GetDocumentHeight(web_contents());
  63. int frame_width = 100; // Ad density by height is independent of frame width.
  64. int frame_height = document_height * 0.45;
  65. // Create the frame with b.com as origin to not get caught by
  66. // restricted ad tagging.
  67. page_load_metrics::CreateAndWaitForIframeAtRect(
  68. web_contents(), waiter.get(),
  69. embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"),
  70. gfx::Rect(0, 0, frame_width, frame_height));
  71. // Delete the page load metrics test waiter instead of reinitializing it
  72. // for the next page load.
  73. waiter.reset();
  74. EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
  75. // blank_with_adiframe_writer loads a script tagged as an ad, verify it is not
  76. // loaded and the subresource filter UI for ad blocking is shown.
  77. EXPECT_FALSE(
  78. WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
  79. EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents())
  80. ->infobar_count(),
  81. 1u);
  82. EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents())
  83. ->infobar_at(0)
  84. ->delegate()
  85. ->GetIdentifier(),
  86. infobars::InfoBarDelegate::ADS_BLOCKED_INFOBAR_DELEGATE_ANDROID);
  87. histogram_tester.ExpectBucketCount(
  88. kAdsInterventionRecordedHistogram,
  89. static_cast<int>(subresource_filter::mojom::AdsViolation::
  90. kMobileAdDensityByHeightAbove30),
  91. 1);
  92. }
  93. IN_PROC_BROWSER_TEST_F(
  94. AdDensityViolationBrowserTest,
  95. MobilePageAdDensityByHeightBelow30_AdInterventionNotTriggered) {
  96. base::HistogramTester histogram_tester;
  97. ukm::TestAutoSetUkmRecorder ukm_recorder;
  98. auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
  99. web_contents());
  100. const GURL url(embedded_test_server()->GetURL(
  101. "a.com", "/ads_observer/blank_with_adiframe_writer.html"));
  102. waiter->SetMainFrameIntersectionExpectation();
  103. EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
  104. waiter->Wait();
  105. int document_height = page_load_metrics::GetDocumentHeight(web_contents());
  106. int frame_width = 100; // Ad density by height is independent of frame width.
  107. int frame_height = document_height * 0.25;
  108. // Create the frame with b.com as origin to not get caught by
  109. // restricted ad tagging.
  110. page_load_metrics::CreateAndWaitForIframeAtRect(
  111. web_contents(), waiter.get(),
  112. embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"),
  113. gfx::Rect(0, 0, frame_width, frame_height));
  114. // Delete the page load metrics test waiter instead of reinitializing it
  115. // for the next page load.
  116. waiter.reset();
  117. EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
  118. // blank_with_adiframe_writer loads a script tagged as an ad, verify it is
  119. // loaded as ads are not blocked and the subresource filter UI is not
  120. // shown.
  121. EXPECT_TRUE(
  122. WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
  123. // No ads blocked infobar should be shown as we have not triggered the
  124. // intervention.
  125. EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents())
  126. ->infobar_count(),
  127. 0u);
  128. histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0);
  129. }
  130. class AdDensityViolationBrowserTestWithoutEnforcement
  131. : public SubresourceFilterBrowserTest {
  132. public:
  133. AdDensityViolationBrowserTestWithoutEnforcement() = default;
  134. void SetUp() override {
  135. std::vector<base::Feature> enabled = {subresource_filter::kAdTagging};
  136. std::vector<base::Feature> disabled = {
  137. subresource_filter::kAdsInterventionsEnforced};
  138. feature_list_.InitWithFeatures(enabled, disabled);
  139. SubresourceFilterBrowserTest::SetUp();
  140. }
  141. void SetUpOnMainThread() override {
  142. SubresourceFilterBrowserTest::SetUpOnMainThread();
  143. SetRulesetWithRules(
  144. {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")});
  145. }
  146. private:
  147. base::test::ScopedFeatureList feature_list_;
  148. };
  149. IN_PROC_BROWSER_TEST_F(
  150. AdDensityViolationBrowserTestWithoutEnforcement,
  151. MobilePageAdDensityByHeightAbove30_NoAdInterventionTriggered) {
  152. base::HistogramTester histogram_tester;
  153. ukm::TestAutoSetUkmRecorder ukm_recorder;
  154. auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
  155. web_contents());
  156. const GURL url(embedded_test_server()->GetURL(
  157. "a.com", "/ads_observer/blank_with_adiframe_writer.html"));
  158. waiter->SetMainFrameIntersectionExpectation();
  159. EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
  160. waiter->Wait();
  161. int document_height = page_load_metrics::GetDocumentHeight(web_contents());
  162. int frame_width = 100; // Ad density by height is independent of frame width.
  163. int frame_height = document_height * 0.45;
  164. // Create the frame with b.com as origin to not get caught by
  165. // restricted ad tagging.
  166. page_load_metrics::CreateAndWaitForIframeAtRect(
  167. web_contents(), waiter.get(),
  168. embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"),
  169. gfx::Rect(0, 0, frame_width, frame_height));
  170. // Delete the page load metrics test waiter instead of reinitializing it
  171. // for the next page load.
  172. waiter.reset();
  173. EXPECT_TRUE(content::NavigateToURL(web_contents(), url));
  174. // We are not enforcing ad blocking on ads violations, site should load
  175. // as expected without subresource filter UI.
  176. EXPECT_TRUE(
  177. WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame()));
  178. // No ads blocked infobar should be shown as we have not triggered the
  179. // intervention.
  180. EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents())
  181. ->infobar_count(),
  182. 0u);
  183. histogram_tester.ExpectBucketCount(
  184. kAdsInterventionRecordedHistogram,
  185. static_cast<int>(subresource_filter::mojom::AdsViolation::
  186. kMobileAdDensityByHeightAbove30),
  187. 1);
  188. }
  189. } // namespace weblayer