1 // Copyright 2017 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 "components/page_load_metrics/browser/observers/use_counter_page_load_metrics_observer.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/macros.h"
11 #include "base/metrics/histogram_base.h"
12 #include "base/test/metrics/histogram_tester.h"
13 #include "components/page_load_metrics/browser/observers/page_load_metrics_observer_content_test_harness.h"
14 #include "components/page_load_metrics/browser/page_load_tracker.h"
15 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h"
16 #include "url/gurl.h"
17
18 namespace {
19
20 const char kTestUrl[] = "https://www.google.com";
21 using WebFeature = blink::mojom::WebFeature;
22 using CSSSampleId = blink::mojom::CSSSampleId;
23
24 } // namespace
25
26 class UseCounterPageLoadMetricsObserverTest
27 : public page_load_metrics::PageLoadMetricsObserverContentTestHarness {
28 public:
UseCounterPageLoadMetricsObserverTest()29 UseCounterPageLoadMetricsObserverTest() {}
30
HistogramBasicTest(const page_load_metrics::mojom::PageLoadFeatures & first_features,const page_load_metrics::mojom::PageLoadFeatures & second_features=page_load_metrics::mojom::PageLoadFeatures ())31 void HistogramBasicTest(
32 const page_load_metrics::mojom::PageLoadFeatures& first_features,
33 const page_load_metrics::mojom::PageLoadFeatures& second_features =
34 page_load_metrics::mojom::PageLoadFeatures()) {
35 NavigateAndCommit(GURL(kTestUrl));
36 tester()->SimulateFeaturesUpdate(first_features);
37 // Verify that kPageVisits is observed on commit.
38 tester()->histogram_tester().ExpectBucketCount(
39 internal::kFeaturesHistogramName,
40 static_cast<base::Histogram::Sample>(WebFeature::kPageVisits), 1);
41 tester()->histogram_tester().ExpectBucketCount(
42 internal::kFeaturesHistogramMainFrameName,
43 static_cast<base::Histogram::Sample>(WebFeature::kPageVisits), 1);
44 // Verify that page visit is recorded for CSS histograms.
45 tester()->histogram_tester().ExpectBucketCount(
46 internal::kCssPropertiesHistogramName,
47 blink::mojom::CSSSampleId::kTotalPagesMeasured, 1);
48 tester()->histogram_tester().ExpectBucketCount(
49 internal::kAnimatedCssPropertiesHistogramName,
50 blink::mojom::CSSSampleId::kTotalPagesMeasured, 1);
51
52 for (auto feature : first_features.features) {
53 tester()->histogram_tester().ExpectBucketCount(
54 internal::kFeaturesHistogramName,
55 static_cast<base::Histogram::Sample>(feature), 1);
56 tester()->histogram_tester().ExpectBucketCount(
57 internal::kFeaturesHistogramMainFrameName,
58 static_cast<base::Histogram::Sample>(feature), 1);
59 }
60
61 tester()->SimulateFeaturesUpdate(second_features);
62 for (auto feature : first_features.features) {
63 tester()->histogram_tester().ExpectBucketCount(
64 internal::kFeaturesHistogramName,
65 static_cast<base::Histogram::Sample>(feature), 1);
66 tester()->histogram_tester().ExpectBucketCount(
67 internal::kFeaturesHistogramMainFrameName,
68 static_cast<base::Histogram::Sample>(feature), 1);
69 }
70 for (auto feature : second_features.features) {
71 tester()->histogram_tester().ExpectBucketCount(
72 internal::kFeaturesHistogramName,
73 static_cast<base::Histogram::Sample>(feature), 1);
74 tester()->histogram_tester().ExpectBucketCount(
75 internal::kFeaturesHistogramMainFrameName,
76 static_cast<base::Histogram::Sample>(feature), 1);
77 }
78 }
79
CssHistogramBasicTest(const page_load_metrics::mojom::PageLoadFeatures & first_features,const page_load_metrics::mojom::PageLoadFeatures & second_features=page_load_metrics::mojom::PageLoadFeatures ())80 void CssHistogramBasicTest(
81 const page_load_metrics::mojom::PageLoadFeatures& first_features,
82 const page_load_metrics::mojom::PageLoadFeatures& second_features =
83 page_load_metrics::mojom::PageLoadFeatures()) {
84 NavigateAndCommit(GURL(kTestUrl));
85 tester()->SimulateFeaturesUpdate(first_features);
86 // Verify that page visit is recorded for CSS histograms.
87 tester()->histogram_tester().ExpectBucketCount(
88 internal::kCssPropertiesHistogramName,
89 blink::mojom::CSSSampleId::kTotalPagesMeasured, 1);
90
91 for (auto feature : first_features.css_properties) {
92 tester()->histogram_tester().ExpectBucketCount(
93 internal::kCssPropertiesHistogramName, feature, 1);
94 }
95
96 tester()->SimulateFeaturesUpdate(second_features);
97 for (auto feature : first_features.css_properties) {
98 tester()->histogram_tester().ExpectBucketCount(
99 internal::kCssPropertiesHistogramName, feature, 1);
100 }
101 for (auto feature : second_features.css_properties) {
102 tester()->histogram_tester().ExpectBucketCount(
103 internal::kCssPropertiesHistogramName, feature, 1);
104 }
105 }
106
AnimatedCssHistogramBasicTest(const page_load_metrics::mojom::PageLoadFeatures & first_features,const page_load_metrics::mojom::PageLoadFeatures & second_features=page_load_metrics::mojom::PageLoadFeatures ())107 void AnimatedCssHistogramBasicTest(
108 const page_load_metrics::mojom::PageLoadFeatures& first_features,
109 const page_load_metrics::mojom::PageLoadFeatures& second_features =
110 page_load_metrics::mojom::PageLoadFeatures()) {
111 NavigateAndCommit(GURL(kTestUrl));
112 tester()->SimulateFeaturesUpdate(first_features);
113 // Verify that page visit is recorded for CSS histograms.
114 tester()->histogram_tester().ExpectBucketCount(
115 internal::kAnimatedCssPropertiesHistogramName,
116 blink::mojom::CSSSampleId::kTotalPagesMeasured, 1);
117
118 for (auto feature : first_features.animated_css_properties) {
119 tester()->histogram_tester().ExpectBucketCount(
120 internal::kAnimatedCssPropertiesHistogramName, feature, 1);
121 }
122
123 tester()->SimulateFeaturesUpdate(second_features);
124 for (auto feature : first_features.animated_css_properties) {
125 tester()->histogram_tester().ExpectBucketCount(
126 internal::kAnimatedCssPropertiesHistogramName, feature, 1);
127 }
128 for (auto feature : second_features.animated_css_properties) {
129 tester()->histogram_tester().ExpectBucketCount(
130 internal::kAnimatedCssPropertiesHistogramName, feature, 1);
131 }
132 }
133
134 protected:
RegisterObservers(page_load_metrics::PageLoadTracker * tracker)135 void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
136 tracker->AddObserver(std::make_unique<UseCounterPageLoadMetricsObserver>());
137 }
138
139 private:
140 DISALLOW_COPY_AND_ASSIGN(UseCounterPageLoadMetricsObserverTest);
141 };
142
TEST_F(UseCounterPageLoadMetricsObserverTest,CountOneFeature)143 TEST_F(UseCounterPageLoadMetricsObserverTest, CountOneFeature) {
144 std::vector<WebFeature> features({WebFeature::kFetch});
145 page_load_metrics::mojom::PageLoadFeatures page_load_features;
146 page_load_features.features = features;
147 HistogramBasicTest(page_load_features);
148 }
149
TEST_F(UseCounterPageLoadMetricsObserverTest,CountFeatures)150 TEST_F(UseCounterPageLoadMetricsObserverTest, CountFeatures) {
151 std::vector<WebFeature> features_0(
152 {WebFeature::kFetch, WebFeature::kFetchBodyStream});
153 std::vector<WebFeature> features_1({WebFeature::kWindowFind});
154 page_load_metrics::mojom::PageLoadFeatures page_load_features_0;
155 page_load_metrics::mojom::PageLoadFeatures page_load_features_1;
156 page_load_features_0.features = features_0;
157 page_load_features_1.features = features_1;
158 HistogramBasicTest(page_load_features_0, page_load_features_1);
159 }
160
TEST_F(UseCounterPageLoadMetricsObserverTest,CountDuplicatedFeatures)161 TEST_F(UseCounterPageLoadMetricsObserverTest, CountDuplicatedFeatures) {
162 std::vector<WebFeature> features_0(
163 {WebFeature::kFetch, WebFeature::kFetch, WebFeature::kFetchBodyStream});
164 std::vector<WebFeature> features_1(
165 {WebFeature::kFetch, WebFeature::kWindowFind});
166 page_load_metrics::mojom::PageLoadFeatures page_load_features_0;
167 page_load_metrics::mojom::PageLoadFeatures page_load_features_1;
168 page_load_features_0.features = features_0;
169 page_load_features_1.features = features_1;
170 HistogramBasicTest(page_load_features_0, page_load_features_1);
171 }
172
TEST_F(UseCounterPageLoadMetricsObserverTest,RecordCSSProperties)173 TEST_F(UseCounterPageLoadMetricsObserverTest, RecordCSSProperties) {
174 // CSSPropertyID::kFont (5), CSSPropertyID::kZoom (19)
175 page_load_metrics::mojom::PageLoadFeatures page_load_features_0;
176 page_load_metrics::mojom::PageLoadFeatures page_load_features_1;
177 page_load_features_0.css_properties = {CSSSampleId::kFont,
178 CSSSampleId::kZoom};
179 page_load_features_1.css_properties = {CSSSampleId::kZoom};
180 CssHistogramBasicTest(page_load_features_0, page_load_features_1);
181 }
182
TEST_F(UseCounterPageLoadMetricsObserverTest,RecordAnimatedCSSProperties)183 TEST_F(UseCounterPageLoadMetricsObserverTest, RecordAnimatedCSSProperties) {
184 page_load_metrics::mojom::PageLoadFeatures page_load_features_0;
185 page_load_metrics::mojom::PageLoadFeatures page_load_features_1;
186 page_load_features_0.css_properties = {CSSSampleId::kFont,
187 CSSSampleId::kZoom};
188 page_load_features_1.css_properties = {CSSSampleId::kZoom};
189 AnimatedCssHistogramBasicTest(page_load_features_0, page_load_features_1);
190 }
191
TEST_F(UseCounterPageLoadMetricsObserverTest,RecordCSSPropertiesInRange)192 TEST_F(UseCounterPageLoadMetricsObserverTest, RecordCSSPropertiesInRange) {
193 page_load_metrics::mojom::PageLoadFeatures page_load_features;
194 page_load_features.css_properties = {CSSSampleId::kColor,
195 CSSSampleId::kMaxValue};
196 CssHistogramBasicTest(page_load_features);
197 }
198