1 // Copyright 2018 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 "chrome/browser/page_load_metrics/observers/live_tab_count_page_load_metrics_observer.h"
6
7 #include <array>
8 #include <memory>
9
10 #include "base/time/time.h"
11 #include "chrome/browser/page_load_metrics/observers/histogram_suffixes.h"
12 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
13 #include "components/page_load_metrics/browser/page_load_tracker.h"
14 #include "components/page_load_metrics/common/test/page_load_metrics_test_util.h"
15 #include "components/tab_count_metrics/tab_count_metrics.h"
16 #include "content/public/browser/web_contents.h"
17 #include "url/gurl.h"
18
19 const char kDefaultTestUrl[] = "https://google.com";
20
21 enum TabState { kForeground, kBackground };
22
23 using BucketCountArray =
24 std::array<size_t, tab_count_metrics::kNumTabCountBuckets>;
25
26 class TestLiveTabCountPageLoadMetricsObserver
27 : public LiveTabCountPageLoadMetricsObserver {
28 public:
TestLiveTabCountPageLoadMetricsObserver(size_t live_tab_count)29 explicit TestLiveTabCountPageLoadMetricsObserver(size_t live_tab_count)
30 : live_tab_count_(live_tab_count) {}
~TestLiveTabCountPageLoadMetricsObserver()31 ~TestLiveTabCountPageLoadMetricsObserver() override {}
32
33 private:
GetLiveTabCount() const34 size_t GetLiveTabCount() const override { return live_tab_count_; }
35
36 const int live_tab_count_;
37 };
38
39 class LiveTabCountPageLoadMetricsObserverTest
40 : public page_load_metrics::PageLoadMetricsObserverTestHarness,
41 public testing::WithParamInterface<TabState> {
42 public:
LiveTabCountPageLoadMetricsObserverTest()43 LiveTabCountPageLoadMetricsObserverTest() : live_tab_count_(0) {}
44
SimulatePageLoad(int live_tab_count,TabState tab_state)45 void SimulatePageLoad(int live_tab_count, TabState tab_state) {
46 live_tab_count_ = live_tab_count;
47
48 page_load_metrics::mojom::PageLoadTiming timing;
49 page_load_metrics::InitPageLoadTimingForTest(&timing);
50 timing.parse_timing->parse_start = base::TimeDelta::FromMilliseconds(10);
51 timing.navigation_start = base::Time::FromDoubleT(1);
52 timing.paint_timing->first_contentful_paint =
53 base::TimeDelta::FromMilliseconds(300);
54 timing.paint_timing->first_meaningful_paint =
55 base::TimeDelta::FromMilliseconds(700);
56 timing.interactive_timing->first_input_delay =
57 base::TimeDelta::FromMilliseconds(5);
58 timing.interactive_timing->first_input_timestamp =
59 base::TimeDelta::FromMilliseconds(4780);
60 PopulateRequiredTimingFields(&timing);
61
62 if (tab_state == kBackground) {
63 // Start in background.
64 web_contents()->WasHidden();
65 }
66
67 NavigateAndCommit(GURL(kDefaultTestUrl));
68
69 if (tab_state == kBackground) {
70 // Foreground the tab.
71 web_contents()->WasShown();
72 }
73
74 tester()->SimulateTimingUpdate(timing);
75 }
76
77 protected:
RegisterObservers(page_load_metrics::PageLoadTracker * tracker)78 void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
79 tracker->AddObserver(
80 std::make_unique<TestLiveTabCountPageLoadMetricsObserver>(
81 live_tab_count_));
82 }
83
ValidateHistograms(const char * page_load_histogram_suffix,BucketCountArray & expected_counts)84 void ValidateHistograms(const char* page_load_histogram_suffix,
85 BucketCountArray& expected_counts) {
86 const std::string histogram_prefix =
87 std::string(internal::kHistogramPrefixLiveTabCount) +
88 std::string(page_load_histogram_suffix);
89 for (size_t bucket = 0; bucket < expected_counts.size(); bucket++) {
90 tester()->histogram_tester().ExpectTotalCount(
91 tab_count_metrics::HistogramName(histogram_prefix,
92 /* live_tabs_only = */ true, bucket),
93 expected_counts[bucket]);
94 }
95 }
96
97 private:
98 size_t live_tab_count_;
99 };
100
TEST_P(LiveTabCountPageLoadMetricsObserverTest,LoadTabs100)101 TEST_P(LiveTabCountPageLoadMetricsObserverTest, LoadTabs100) {
102 TabState tab_state = GetParam();
103 BucketCountArray counts = {0};
104
105 size_t bucket;
106 constexpr size_t kMaxLiveTabCount = 100;
107 // Simulate loading pages with the number of live tabs ranging from 0 to
108 // kMaxLiveTabCount.
109 for (size_t num_tabs = 0; num_tabs <= kMaxLiveTabCount; num_tabs++) {
110 bucket = tab_count_metrics::BucketForTabCount(num_tabs);
111 SimulatePageLoad(num_tabs, tab_state);
112 // We only record metrics if the tab was foregrounded the entire time
113 // preceding the event that caused the metrics to be recorded.
114 if (tab_state == TabState::kForeground)
115 ++counts[bucket];
116 ValidateHistograms(internal::kHistogramFirstContentfulPaintSuffix, counts);
117 ValidateHistograms(internal::kHistogramFirstMeaningfulPaintSuffix, counts);
118 ValidateHistograms(internal::kHistogramFirstInputDelaySuffix, counts);
119 }
120 // Make sure we are testing each bucket.
121 EXPECT_EQ(bucket, tab_count_metrics::kNumTabCountBuckets - 1);
122 }
123
124 INSTANTIATE_TEST_SUITE_P(Foreground,
125 LiveTabCountPageLoadMetricsObserverTest,
126 testing::Values(TabState::kForeground));
127
128 INSTANTIATE_TEST_SUITE_P(Background,
129 LiveTabCountPageLoadMetricsObserverTest,
130 testing::Values(TabState::kBackground));
131