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