1 // Copyright (c) 2015 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.
5 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/process/kill.h"
9 #include "base/test/histogram_tester.h"
10 #include "base/time/time.h"
11 #include "components/page_load_metrics/common/page_load_metrics_messages.h"
12 #include "content/public/browser/navigation_handle.h"
13 #include "content/public/browser/render_frame_host.h"
14 #include "content/public/test/test_renderer_host.h"
15 #include "content/public/test/web_contents_tester.h"
17 namespace page_load_metrics
{
21 const char kDefaultTestUrl
[] = "https://google.com";
22 const char kDefaultTestUrlAnchor
[] = "https://google.com#samepage";
23 const char kDefaultTestUrl2
[] = "https://whatever.com";
25 const char kHistogramNameFirstLayout
[] =
26 "PageLoad.Timing.NavigationToFirstLayout";
27 const char kHistogramNameDomContent
[] =
28 "PageLoad.Timing.NavigationToDOMContentLoadedEventFired";
29 const char kHistogramNameLoad
[] =
30 "PageLoad.Timing.NavigationToLoadEventFired";
34 class MetricsWebContentsObserverTest
35 : public content::RenderViewHostTestHarness
{
37 MetricsWebContentsObserverTest() {}
39 void SetUp() override
{
40 RenderViewHostTestHarness::SetUp();
41 observer_
= make_scoped_ptr(new MetricsWebContentsObserver(web_contents()));
44 void AssertNoHistogramsLogged() {
45 histogram_tester_
.ExpectTotalCount(kHistogramNameDomContent
, 0);
46 histogram_tester_
.ExpectTotalCount(kHistogramNameLoad
, 0);
47 histogram_tester_
.ExpectTotalCount(kHistogramNameFirstLayout
, 0);
51 base::HistogramTester histogram_tester_
;
52 scoped_ptr
<MetricsWebContentsObserver
> observer_
;
55 TEST_F(MetricsWebContentsObserverTest
, NoMetrics
) {
56 AssertNoHistogramsLogged();
59 TEST_F(MetricsWebContentsObserverTest
, NotInMainFrame
) {
60 base::TimeDelta first_layout
= base::TimeDelta::FromMilliseconds(1);
62 PageLoadTiming timing
;
63 timing
.navigation_start
= base::Time::FromDoubleT(1);
64 timing
.first_layout
= first_layout
;
66 content::WebContentsTester
* web_contents_tester
=
67 content::WebContentsTester::For(web_contents());
68 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
70 content::RenderFrameHostTester
* rfh_tester
=
71 content::RenderFrameHostTester::For(main_rfh());
72 content::RenderFrameHost
* subframe
= rfh_tester
->AppendChild("subframe");
74 content::RenderFrameHostTester
* subframe_tester
=
75 content::RenderFrameHostTester::For(subframe
);
76 subframe_tester
->SimulateNavigationStart(GURL(kDefaultTestUrl2
));
77 subframe_tester
->SimulateNavigationCommit(GURL(kDefaultTestUrl2
));
78 observer_
->OnMessageReceived(
79 PageLoadMetricsMsg_TimingUpdated(observer_
->routing_id(), timing
),
81 subframe_tester
->SimulateNavigationStop();
83 // Navigate again to see if the timing updated for a subframe message.
84 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
86 AssertNoHistogramsLogged();
89 TEST_F(MetricsWebContentsObserverTest
, SamePageNoTrigger
) {
90 base::TimeDelta first_layout
= base::TimeDelta::FromMilliseconds(1);
92 PageLoadTiming timing
;
93 timing
.navigation_start
= base::Time::FromDoubleT(1);
94 timing
.first_layout
= first_layout
;
96 content::WebContentsTester
* web_contents_tester
=
97 content::WebContentsTester::For(web_contents());
98 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
100 observer_
->OnMessageReceived(
101 PageLoadMetricsMsg_TimingUpdated(observer_
->routing_id(), timing
),
102 web_contents()->GetMainFrame());
103 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrlAnchor
));
104 // A same page navigation shouldn't trigger logging UMA for the original.
105 AssertNoHistogramsLogged();
108 TEST_F(MetricsWebContentsObserverTest
, SamePageNoTriggerUntilTrueNavCommit
) {
109 base::TimeDelta first_layout
= base::TimeDelta::FromMilliseconds(1);
111 PageLoadTiming timing
;
112 timing
.navigation_start
= base::Time::FromDoubleT(1);
113 timing
.first_layout
= first_layout
;
115 content::WebContentsTester
* web_contents_tester
=
116 content::WebContentsTester::For(web_contents());
117 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
119 observer_
->OnMessageReceived(
120 PageLoadMetricsMsg_TimingUpdated(observer_
->routing_id(), timing
),
121 web_contents()->GetMainFrame());
122 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrlAnchor
));
123 // A same page navigation shouldn't trigger logging UMA for the original.
124 AssertNoHistogramsLogged();
126 // But we should keep the timing info and log it when we get another
128 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl2
));
129 histogram_tester_
.ExpectTotalCount(kHistogramNameDomContent
, 0);
130 histogram_tester_
.ExpectTotalCount(kHistogramNameLoad
, 0);
131 histogram_tester_
.ExpectTotalCount(kHistogramNameFirstLayout
, 1);
132 histogram_tester_
.ExpectBucketCount(kHistogramNameFirstLayout
,
133 first_layout
.InMilliseconds(), 1);
136 TEST_F(MetricsWebContentsObserverTest
, SingleMetricAfterCommit
) {
137 base::TimeDelta first_layout
= base::TimeDelta::FromMilliseconds(1);
139 PageLoadTiming timing
;
140 timing
.navigation_start
= base::Time::FromDoubleT(1);
141 timing
.first_layout
= first_layout
;
143 content::WebContentsTester
* web_contents_tester
=
144 content::WebContentsTester::For(web_contents());
145 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
147 observer_
->OnMessageReceived(
148 PageLoadMetricsMsg_TimingUpdated(observer_
->routing_id(), timing
),
149 web_contents()->GetMainFrame());
151 AssertNoHistogramsLogged();
153 // Navigate again to force histogram recording.
154 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl2
));
156 histogram_tester_
.ExpectTotalCount(kHistogramNameDomContent
, 0);
157 histogram_tester_
.ExpectTotalCount(kHistogramNameLoad
, 0);
158 histogram_tester_
.ExpectTotalCount(kHistogramNameFirstLayout
, 1);
159 histogram_tester_
.ExpectBucketCount(kHistogramNameFirstLayout
,
160 first_layout
.InMilliseconds(), 1);
163 TEST_F(MetricsWebContentsObserverTest
, MultipleMetricsAfterCommits
) {
164 base::TimeDelta first_layout_1
= base::TimeDelta::FromMilliseconds(1);
165 base::TimeDelta first_layout_2
= base::TimeDelta::FromMilliseconds(20);
166 base::TimeDelta response
= base::TimeDelta::FromMilliseconds(10);
167 base::TimeDelta dom_content
= base::TimeDelta::FromMilliseconds(40);
168 base::TimeDelta load
= base::TimeDelta::FromMilliseconds(100);
170 PageLoadTiming timing
;
171 timing
.navigation_start
= base::Time::FromDoubleT(1);
172 timing
.first_layout
= first_layout_1
;
173 timing
.response_start
= response
;
174 timing
.dom_content_loaded_event_start
= dom_content
;
175 timing
.load_event_start
= load
;
177 content::WebContentsTester
* web_contents_tester
=
178 content::WebContentsTester::For(web_contents());
179 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
181 observer_
->OnMessageReceived(
182 PageLoadMetricsMsg_TimingUpdated(observer_
->routing_id(), timing
),
183 web_contents()->GetMainFrame());
185 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl2
));
187 PageLoadTiming timing2
;
188 timing2
.navigation_start
= base::Time::FromDoubleT(200);
189 timing2
.first_layout
= first_layout_2
;
191 observer_
->OnMessageReceived(
192 PageLoadMetricsMsg_TimingUpdated(observer_
->routing_id(), timing2
),
193 web_contents()->GetMainFrame());
195 web_contents_tester
->NavigateAndCommit(GURL(kDefaultTestUrl
));
197 histogram_tester_
.ExpectBucketCount(kHistogramNameFirstLayout
,
198 first_layout_1
.InMilliseconds(), 1);
199 histogram_tester_
.ExpectTotalCount(kHistogramNameFirstLayout
, 2);
200 histogram_tester_
.ExpectBucketCount(kHistogramNameFirstLayout
,
201 first_layout_1
.InMilliseconds(), 1);
202 histogram_tester_
.ExpectBucketCount(kHistogramNameFirstLayout
,
203 first_layout_2
.InMilliseconds(), 1);
205 histogram_tester_
.ExpectTotalCount(kHistogramNameDomContent
, 1);
206 histogram_tester_
.ExpectBucketCount(kHistogramNameDomContent
,
207 dom_content
.InMilliseconds(), 1);
209 histogram_tester_
.ExpectTotalCount(kHistogramNameLoad
, 1);
210 histogram_tester_
.ExpectBucketCount(kHistogramNameLoad
, load
.InMilliseconds(),
214 } // namespace page_load_metrics