// Copyright 2015 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 "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/use_counter/css_property_id.mojom-blink.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/html_html_element.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"

namespace {
const char kExtensionFeaturesHistogramName[] =
    "Blink.UseCounter.Extensions.Features";

const char kExtensionUrl[] = "chrome-extension://dummysite/";

int GetPageVisitsBucketforHistogram(const std::string& histogram_name) {
  if (histogram_name.find("CSS") == std::string::npos)
    return static_cast<int>(blink::mojom::WebFeature::kPageVisits);
  // For CSS histograms, the page visits bucket should be 1.
  return static_cast<int>(
      blink::mojom::blink::CSSSampleId::kTotalPagesMeasured);
}

}  // namespace

namespace blink {
using WebFeature = mojom::WebFeature;

class UseCounterHelperTest : public testing::Test {
 public:
  UseCounterHelperTest() : dummy_(std::make_unique<DummyPageHolder>()) {
    Page::InsertOrdinaryPageForTesting(&dummy_->GetPage());
  }

  int ToSampleId(CSSPropertyID property) const {
    return static_cast<int>(GetCSSSampleId(property));
  }

  bool IsInternal(CSSPropertyID property) const {
    return CSSProperty::Get(property).IsInternal();
  }

 protected:
  LocalFrame* GetFrame() { return &dummy_->GetFrame(); }
  void SetIsViewSource() { dummy_->GetDocument().SetIsViewSource(true); }
  void SetURL(const KURL& url) { dummy_->GetDocument().SetURL(url); }
  Document& GetDocument() { return dummy_->GetDocument(); }

  std::unique_ptr<DummyPageHolder> dummy_;
  HistogramTester histogram_tester_;

  void UpdateAllLifecyclePhases(Document& document) {
    document.View()->UpdateAllLifecyclePhasesForTest();
  }
};

TEST_F(UseCounterHelperTest, RecordingExtensions) {
  const std::string histogram = kExtensionFeaturesHistogramName;
  constexpr auto item = mojom::WebFeature::kFetch;
  constexpr auto second_item = WebFeature::kFetchBodyStream;
  const std::string url = kExtensionUrl;
  UseCounterHelper::Context context = UseCounterHelper::kExtensionContext;
  int page_visits_bucket = GetPageVisitsBucketforHistogram(histogram);

  UseCounterHelper use_counter0(context, UseCounterHelper::kCommited);

  // Test recording a single (arbitrary) counter
  EXPECT_FALSE(use_counter0.HasRecordedMeasurement(item));
  use_counter0.RecordMeasurement(item, *GetFrame());
  EXPECT_TRUE(use_counter0.HasRecordedMeasurement(item));
  histogram_tester_.ExpectUniqueSample(histogram, static_cast<int>(item), 1);
  // Test that repeated measurements have no effect
  use_counter0.RecordMeasurement(item, *GetFrame());
  histogram_tester_.ExpectUniqueSample(histogram, static_cast<int>(item), 1);

  // Test recording a different sample
  EXPECT_FALSE(use_counter0.HasRecordedMeasurement(second_item));
  use_counter0.RecordMeasurement(second_item, *GetFrame());
  EXPECT_TRUE(use_counter0.HasRecordedMeasurement(second_item));
  histogram_tester_.ExpectBucketCount(histogram, static_cast<int>(item), 1);
  histogram_tester_.ExpectBucketCount(histogram, static_cast<int>(second_item),
                                      1);
  histogram_tester_.ExpectTotalCount(histogram, 2);

  // After a page load, the histograms will be updated, even when the URL
  // scheme is internal
  UseCounterHelper use_counter1(context);
  SetURL(url_test_helpers::ToKURL(url));
  use_counter1.DidCommitLoad(GetFrame());
  histogram_tester_.ExpectBucketCount(histogram, static_cast<int>(item), 1);
  histogram_tester_.ExpectBucketCount(histogram, static_cast<int>(second_item),
                                      1);
  histogram_tester_.ExpectBucketCount(histogram, page_visits_bucket, 1);
  histogram_tester_.ExpectTotalCount(histogram, 3);

  // Now a repeat measurement should get recorded again, exactly once
  EXPECT_FALSE(use_counter1.HasRecordedMeasurement(item));
  use_counter1.RecordMeasurement(item, *GetFrame());
  use_counter1.RecordMeasurement(item, *GetFrame());
  EXPECT_TRUE(use_counter1.HasRecordedMeasurement(item));
  histogram_tester_.ExpectBucketCount(histogram, static_cast<int>(item), 2);
  histogram_tester_.ExpectTotalCount(histogram, 4);
}

TEST_F(UseCounterHelperTest, CSSSelectorPseudoWhere) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorPseudoWhere;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<style>.a+:where(.b, .c+.d) { color: red; }</style>");
  EXPECT_TRUE(document.IsUseCounted(feature));
  EXPECT_FALSE(document.IsUseCounted(WebFeature::kCSSSelectorPseudoIs));
}

/*
 * Counter-specific tests
 *
 * NOTE: Most individual UseCounters don't need dedicated test cases.  They are
 * "tested" by analyzing the data they generate including on some known pages.
 * Feel free to add tests for counters where the triggering logic is
 * non-trivial, but it's not required. Manual analysis is necessary to trust the
 * data anyway, real-world pages are full of edge-cases and surprises that you
 * won't find in unit testing anyway.
 */

TEST_F(UseCounterHelperTest, CSSSelectorPseudoAnyLink) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorPseudoAnyLink;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<style>:any-link { color: red; }</style>");
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSSelectorPseudoWebkitAnyLink) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorPseudoWebkitAnyLink;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<style>:-webkit-any-link { color: red; }</style>");
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSTypedOMStylePropertyMap) {
  UseCounterHelper use_counter;
  WebFeature feature = WebFeature::kCSSTypedOMStylePropertyMap;
  EXPECT_FALSE(GetDocument().IsUseCounted(feature));
  GetDocument().CountUse(feature);
  EXPECT_TRUE(GetDocument().IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSSelectorPseudoIs) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorPseudoIs;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<style>.a+:is(.b, .c+.d) { color: red; }</style>");
  EXPECT_TRUE(document.IsUseCounted(feature));
  EXPECT_FALSE(document.IsUseCounted(WebFeature::kCSSSelectorPseudoWhere));
}

TEST_F(UseCounterHelperTest, CSSSelectorPseudoDir) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorPseudoDir;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<style>:dir(ltr) { color: red; }</style>");
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageColumnIndefiniteWidth) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-columns: 50%;'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight1) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-rows: 50%;'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight2) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-rows: 50% 50%;'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight3) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-rows: 100% 100%;'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight4) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-rows: minmax(50%, "
      "100%);'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight5) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; max-height: 0; grid-template-rows: "
      "100%;'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight6) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-rows: 100%;'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight7) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-grid; grid-template-rows: minmax(100%, "
      "100%);'>"
      "</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSFlexibleBox) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSFlexibleBox;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: flex;'>flexbox</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSFlexibleBoxInline) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSFlexibleBox;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML(
      "<div style='display: inline-flex;'>flexbox</div>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSFlexibleBoxButton) {
  // LayoutButton is a subclass of LayoutFlexibleBox, however we don't want it
  // to be counted as usage of flexboxes as it's an implementation detail.
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSFlexibleBox;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.documentElement()->setInnerHTML("<button>button</button>");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));
}

class DeprecationTest : public testing::Test {
 public:
  DeprecationTest()
      : dummy_(std::make_unique<DummyPageHolder>()),
        deprecation_(dummy_->GetPage().GetDeprecation()),
        use_counter_(dummy_->GetDocument().Loader()->GetUseCounterHelper()) {
    Page::InsertOrdinaryPageForTesting(&dummy_->GetPage());
  }

 protected:
  LocalFrame* GetFrame() { return &dummy_->GetFrame(); }

  std::unique_ptr<DummyPageHolder> dummy_;
  Deprecation& deprecation_;
  UseCounterHelper& use_counter_;
};

TEST_F(DeprecationTest, InspectorDisablesDeprecation) {
  // The specific feature we use here isn't important.
  WebFeature feature =
      WebFeature::kCSSSelectorInternalMediaControlsOverlayCastButton;
  CSSPropertyID property = CSSPropertyID::kFontWeight;

  EXPECT_FALSE(deprecation_.IsSuppressed(property));

  deprecation_.MuteForInspector();
  Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
  EXPECT_FALSE(deprecation_.IsSuppressed(property));
  Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
  EXPECT_FALSE(use_counter_.HasRecordedMeasurement(feature));

  deprecation_.MuteForInspector();
  Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
  EXPECT_FALSE(deprecation_.IsSuppressed(property));
  Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
  EXPECT_FALSE(use_counter_.HasRecordedMeasurement(feature));

  deprecation_.UnmuteForInspector();
  Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
  EXPECT_FALSE(deprecation_.IsSuppressed(property));
  Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
  EXPECT_FALSE(use_counter_.HasRecordedMeasurement(feature));

  deprecation_.UnmuteForInspector();
  Deprecation::WarnOnDeprecatedProperties(GetFrame(), property);
  // TODO: use the actually deprecated property to get a deprecation message.
  EXPECT_FALSE(deprecation_.IsSuppressed(property));
  Deprecation::CountDeprecation(GetFrame()->DomWindow(), feature);
  EXPECT_TRUE(use_counter_.HasRecordedMeasurement(feature));
}

TEST_F(UseCounterHelperTest, CSSUnknownNamespacePrefixInSelector) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSUnknownNamespacePrefixInSelector;
  EXPECT_FALSE(document.IsUseCounted(feature));

  document.documentElement()->setInnerHTML(R"HTML(
    <style>
      @namespace svg url(http://www.w3.org/2000/svg);
      svg|a {}
      a {}
    </style>
  )HTML");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));

  document.documentElement()->setInnerHTML("<style>foo|a {}</style>");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSSelectorHostContextInLiveProfile) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorHostContextInLiveProfile;

  document.body()->setInnerHTML(R"HTML(
    <div id="parent">
      <div id="host"></div>
    </div>
  )HTML");

  Element* host = document.getElementById("host");
  ASSERT_TRUE(host);
  ShadowRoot& shadow_root =
      host->AttachShadowRootInternal(ShadowRootType::kOpen);
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));

  shadow_root.setInnerHTML(R"HTML(
      <style>
        :host-context(#parent) span {
          color: green
        }
      </style>
      <span></span>
  )HTML");

  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSSelectorHostContextInSnapshotProfile) {
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kCSSSelectorHostContextInSnapshotProfile;

  document.body()->setInnerHTML(R"HTML(
    <div id="parent">
      <div id="host"></div>
    </div>
  )HTML");

  Element* host = document.getElementById("host");
  ASSERT_TRUE(host);
  ShadowRoot& shadow_root =
      host->AttachShadowRootInternal(ShadowRootType::kOpen);
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));

  shadow_root.setInnerHTML("<span></span>");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));

  Element* span = shadow_root.QuerySelector(":host-context(#parent) span");
  EXPECT_TRUE(span);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, UniqueCSSSampleIds) {
  HashSet<int> ids;

  for (CSSPropertyID property : CSSPropertyIDList()) {
    if (IsInternal(property))
      continue;
    EXPECT_FALSE(ids.Contains(ToSampleId(property)));
    ids.insert(ToSampleId(property));
  }

  for (CSSPropertyID property : kCSSPropertyAliasList) {
    EXPECT_FALSE(ids.Contains(ToSampleId(property)));
    ids.insert(ToSampleId(property));
  }
}

TEST_F(UseCounterHelperTest, MaximumCSSSampleId) {
  int max_sample_id = 0;

  for (CSSPropertyID property : CSSPropertyIDList()) {
    if (IsInternal(property))
      continue;
    max_sample_id = std::max(max_sample_id, ToSampleId(property));
  }

  for (CSSPropertyID property : kCSSPropertyAliasList)
    max_sample_id = std::max(max_sample_id, ToSampleId(property));

  EXPECT_EQ(static_cast<int>(mojom::blink::CSSSampleId::kMaxValue),
            max_sample_id);
}

TEST_F(UseCounterHelperTest, CSSMarkerPseudoElementUA) {
  // Check that UA styles for list markers are not counted.
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kHasMarkerPseudoElement;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.body()->setInnerHTML(R"HTML(
    <style>
      li::before {
        content: "[before]";
        display: list-item;
      }
    </style>
    <ul>
      <li style="list-style: decimal outside"></li>
      <li style="list-style: decimal inside"></li>
      <li style="list-style: disc outside"></li>
      <li style="list-style: disc inside"></li>
      <li style="list-style: '- ' outside"></li>
      <li style="list-style: '- ' inside"></li>
      <li style="list-style: linear-gradient(blue, cyan) outside"></li>
      <li style="list-style: linear-gradient(blue, cyan) inside"></li>
      <li style="list-style: none outside"></li>
      <li style="list-style: none inside"></li>
    </ul>
  )HTML");
  UpdateAllLifecyclePhases(document);
  EXPECT_FALSE(document.IsUseCounted(feature));
}

TEST_F(UseCounterHelperTest, CSSMarkerPseudoElementAuthor) {
  // Check that author styles for list markers are counted.
  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
  Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
  Document& document = dummy_page_holder->GetDocument();
  WebFeature feature = WebFeature::kHasMarkerPseudoElement;
  EXPECT_FALSE(document.IsUseCounted(feature));
  document.body()->setInnerHTML(R"HTML(
    <style>
      li::marker {
        color: blue;
      }
    </style>
    <ul>
      <li></li>
    </ul>
  )HTML");
  UpdateAllLifecyclePhases(document);
  EXPECT_TRUE(document.IsUseCounted(feature));
}

}  // namespace blink
