OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" | 5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 const char kFilteredCommitUrl[] = "https://whatever.com/ignore-on-commit"; | 37 const char kFilteredCommitUrl[] = "https://whatever.com/ignore-on-commit"; |
38 | 38 |
39 // Simple PageLoadMetricsObserver that copies observed PageLoadTimings into the | 39 // Simple PageLoadMetricsObserver that copies observed PageLoadTimings into the |
40 // provided std::vector, so they can be analyzed by unit tests. | 40 // provided std::vector, so they can be analyzed by unit tests. |
41 class TestPageLoadMetricsObserver | 41 class TestPageLoadMetricsObserver |
42 : public PageLoadMetricsObserver, | 42 : public PageLoadMetricsObserver, |
43 public MetricsWebContentsObserver::TestingObserver { | 43 public MetricsWebContentsObserver::TestingObserver { |
44 public: | 44 public: |
45 TestPageLoadMetricsObserver( | 45 TestPageLoadMetricsObserver( |
46 content::WebContents* web_contents, | 46 content::WebContents* web_contents, |
47 std::vector<PageLoadTiming>* updated_timings, | 47 std::vector<mojom::PageLoadTimingPtr>* updated_timings, |
48 std::vector<PageLoadTiming>* updated_subframe_timings, | 48 std::vector<mojom::PageLoadTimingPtr>* updated_subframe_timings, |
49 std::vector<PageLoadTiming>* complete_timings, | 49 std::vector<mojom::PageLoadTimingPtr>* complete_timings, |
50 std::vector<GURL>* observed_committed_urls) | 50 std::vector<GURL>* observed_committed_urls) |
51 : MetricsWebContentsObserver::TestingObserver(web_contents), | 51 : MetricsWebContentsObserver::TestingObserver(web_contents), |
52 updated_timings_(updated_timings), | 52 updated_timings_(updated_timings), |
53 updated_subframe_timings_(updated_subframe_timings), | 53 updated_subframe_timings_(updated_subframe_timings), |
54 complete_timings_(complete_timings), | 54 complete_timings_(complete_timings), |
55 observed_committed_urls_(observed_committed_urls) {} | 55 observed_committed_urls_(observed_committed_urls) {} |
56 | 56 |
57 ObservePolicy OnStart(content::NavigationHandle* navigation_handle, | 57 ObservePolicy OnStart(content::NavigationHandle* navigation_handle, |
58 const GURL& currently_committed_url, | 58 const GURL& currently_committed_url, |
59 bool started_in_foreground) override { | 59 bool started_in_foreground) override { |
60 observed_committed_urls_->push_back(currently_committed_url); | 60 observed_committed_urls_->push_back(currently_committed_url); |
61 return CONTINUE_OBSERVING; | 61 return CONTINUE_OBSERVING; |
62 } | 62 } |
63 | 63 |
64 void OnTimingUpdate(const PageLoadTiming& timing, | 64 void OnTimingUpdate(const mojom::PageLoadTiming& timing, |
65 const PageLoadExtraInfo& extra_info) override { | 65 const PageLoadExtraInfo& extra_info) override { |
66 updated_timings_->push_back(timing); | 66 updated_timings_->push_back(timing.Clone()); |
67 } | 67 } |
68 | 68 |
69 void OnTimingUpdated(bool is_main_frame, | 69 void OnTimingUpdated(bool is_main_frame, |
70 const PageLoadTiming& timing, | 70 const mojom::PageLoadTiming& timing, |
71 const PageLoadMetadata& metadata) override { | 71 const mojom::PageLoadMetadata& metadata) override { |
72 if (!is_main_frame) { | 72 if (!is_main_frame) { |
73 updated_subframe_timings_->push_back(timing); | 73 updated_subframe_timings_->push_back(timing.Clone()); |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 void OnComplete(const PageLoadTiming& timing, | 77 void OnComplete(const mojom::PageLoadTiming& timing, |
78 const PageLoadExtraInfo& extra_info) override { | 78 const PageLoadExtraInfo& extra_info) override { |
79 complete_timings_->push_back(timing); | 79 complete_timings_->push_back(timing.Clone()); |
80 } | 80 } |
81 | 81 |
82 ObservePolicy FlushMetricsOnAppEnterBackground( | 82 ObservePolicy FlushMetricsOnAppEnterBackground( |
83 const PageLoadTiming& timing, | 83 const mojom::PageLoadTiming& timing, |
84 const PageLoadExtraInfo& extra_info) override { | 84 const PageLoadExtraInfo& extra_info) override { |
85 return STOP_OBSERVING; | 85 return STOP_OBSERVING; |
86 } | 86 } |
87 | 87 |
88 private: | 88 private: |
89 std::vector<PageLoadTiming>* const updated_timings_; | 89 std::vector<mojom::PageLoadTimingPtr>* const updated_timings_; |
90 std::vector<PageLoadTiming>* const updated_subframe_timings_; | 90 std::vector<mojom::PageLoadTimingPtr>* const updated_subframe_timings_; |
91 std::vector<PageLoadTiming>* const complete_timings_; | 91 std::vector<mojom::PageLoadTimingPtr>* const complete_timings_; |
92 std::vector<GURL>* const observed_committed_urls_; | 92 std::vector<GURL>* const observed_committed_urls_; |
93 }; | 93 }; |
94 | 94 |
95 // Test PageLoadMetricsObserver that stops observing page loads with certain | 95 // Test PageLoadMetricsObserver that stops observing page loads with certain |
96 // substrings in the URL. | 96 // substrings in the URL. |
97 class FilteringPageLoadMetricsObserver : public PageLoadMetricsObserver { | 97 class FilteringPageLoadMetricsObserver : public PageLoadMetricsObserver { |
98 public: | 98 public: |
99 explicit FilteringPageLoadMetricsObserver( | 99 explicit FilteringPageLoadMetricsObserver( |
100 std::vector<GURL>* completed_filtered_urls) | 100 std::vector<GURL>* completed_filtered_urls) |
101 : completed_filtered_urls_(completed_filtered_urls) {} | 101 : completed_filtered_urls_(completed_filtered_urls) {} |
102 | 102 |
103 ObservePolicy OnStart(content::NavigationHandle* handle, | 103 ObservePolicy OnStart(content::NavigationHandle* handle, |
104 const GURL& currently_committed_url, | 104 const GURL& currently_committed_url, |
105 bool started_in_foreground) override { | 105 bool started_in_foreground) override { |
106 const bool should_ignore = | 106 const bool should_ignore = |
107 handle->GetURL().spec().find("ignore-on-start") != std::string::npos; | 107 handle->GetURL().spec().find("ignore-on-start") != std::string::npos; |
108 return should_ignore ? STOP_OBSERVING : CONTINUE_OBSERVING; | 108 return should_ignore ? STOP_OBSERVING : CONTINUE_OBSERVING; |
109 } | 109 } |
110 | 110 |
111 ObservePolicy OnCommit(content::NavigationHandle* handle) override { | 111 ObservePolicy OnCommit(content::NavigationHandle* handle) override { |
112 const bool should_ignore = | 112 const bool should_ignore = |
113 handle->GetURL().spec().find("ignore-on-commit") != std::string::npos; | 113 handle->GetURL().spec().find("ignore-on-commit") != std::string::npos; |
114 return should_ignore ? STOP_OBSERVING : CONTINUE_OBSERVING; | 114 return should_ignore ? STOP_OBSERVING : CONTINUE_OBSERVING; |
115 } | 115 } |
116 | 116 |
117 void OnComplete(const PageLoadTiming& timing, | 117 void OnComplete(const mojom::PageLoadTiming& timing, |
118 const PageLoadExtraInfo& extra_info) override { | 118 const PageLoadExtraInfo& extra_info) override { |
119 completed_filtered_urls_->push_back(extra_info.url); | 119 completed_filtered_urls_->push_back(extra_info.url); |
120 } | 120 } |
121 | 121 |
122 private: | 122 private: |
123 std::vector<GURL>* const completed_filtered_urls_; | 123 std::vector<GURL>* const completed_filtered_urls_; |
124 }; | 124 }; |
125 | 125 |
126 class TestPageLoadMetricsEmbedderInterface | 126 class TestPageLoadMetricsEmbedderInterface |
127 : public PageLoadMetricsEmbedderInterface { | 127 : public PageLoadMetricsEmbedderInterface { |
128 public: | 128 public: |
129 explicit TestPageLoadMetricsEmbedderInterface( | 129 explicit TestPageLoadMetricsEmbedderInterface( |
130 content::WebContents* web_contents) | 130 content::WebContents* web_contents) |
131 : web_contents_(web_contents), is_ntp_(false) {} | 131 : web_contents_(web_contents), is_ntp_(false) {} |
132 | 132 |
133 bool IsNewTabPageUrl(const GURL& url) override { return is_ntp_; } | 133 bool IsNewTabPageUrl(const GURL& url) override { return is_ntp_; } |
134 void set_is_ntp(bool is_ntp) { is_ntp_ = is_ntp; } | 134 void set_is_ntp(bool is_ntp) { is_ntp_ = is_ntp; } |
135 void RegisterObservers(PageLoadTracker* tracker) override { | 135 void RegisterObservers(PageLoadTracker* tracker) override { |
136 tracker->AddObserver(base::MakeUnique<TestPageLoadMetricsObserver>( | 136 tracker->AddObserver(base::MakeUnique<TestPageLoadMetricsObserver>( |
137 web_contents_, &updated_timings_, &updated_subframe_timings_, | 137 web_contents_, &updated_timings_, &updated_subframe_timings_, |
138 &complete_timings_, &observed_committed_urls_)); | 138 &complete_timings_, &observed_committed_urls_)); |
139 tracker->AddObserver(base::MakeUnique<FilteringPageLoadMetricsObserver>( | 139 tracker->AddObserver(base::MakeUnique<FilteringPageLoadMetricsObserver>( |
140 &completed_filtered_urls_)); | 140 &completed_filtered_urls_)); |
141 } | 141 } |
142 const std::vector<PageLoadTiming>& updated_timings() const { | 142 const std::vector<mojom::PageLoadTimingPtr>& updated_timings() const { |
143 return updated_timings_; | 143 return updated_timings_; |
144 } | 144 } |
145 const std::vector<PageLoadTiming>& complete_timings() const { | 145 const std::vector<mojom::PageLoadTimingPtr>& complete_timings() const { |
146 return complete_timings_; | 146 return complete_timings_; |
147 } | 147 } |
148 const std::vector<PageLoadTiming>& updated_subframe_timings() const { | 148 const std::vector<mojom::PageLoadTimingPtr>& updated_subframe_timings() |
| 149 const { |
149 return updated_subframe_timings_; | 150 return updated_subframe_timings_; |
150 } | 151 } |
151 | 152 |
152 // currently_committed_urls passed to OnStart(). | 153 // currently_committed_urls passed to OnStart(). |
153 const std::vector<GURL>& observed_committed_urls_from_on_start() const { | 154 const std::vector<GURL>& observed_committed_urls_from_on_start() const { |
154 return observed_committed_urls_; | 155 return observed_committed_urls_; |
155 } | 156 } |
156 | 157 |
157 // committed URLs passed to FilteringPageLoadMetricsObserver::OnComplete(). | 158 // committed URLs passed to FilteringPageLoadMetricsObserver::OnComplete(). |
158 const std::vector<GURL>& completed_filtered_urls() const { | 159 const std::vector<GURL>& completed_filtered_urls() const { |
159 return completed_filtered_urls_; | 160 return completed_filtered_urls_; |
160 } | 161 } |
161 | 162 |
162 private: | 163 private: |
163 std::vector<PageLoadTiming> updated_timings_; | 164 std::vector<mojom::PageLoadTimingPtr> updated_timings_; |
164 std::vector<PageLoadTiming> updated_subframe_timings_; | 165 std::vector<mojom::PageLoadTimingPtr> updated_subframe_timings_; |
165 std::vector<PageLoadTiming> complete_timings_; | 166 std::vector<mojom::PageLoadTimingPtr> complete_timings_; |
166 std::vector<GURL> observed_committed_urls_; | 167 std::vector<GURL> observed_committed_urls_; |
167 std::vector<GURL> completed_filtered_urls_; | 168 std::vector<GURL> completed_filtered_urls_; |
168 content::WebContents* web_contents_; | 169 content::WebContents* web_contents_; |
169 bool is_ntp_; | 170 bool is_ntp_; |
170 }; | 171 }; |
171 | 172 |
172 } // namespace | 173 } // namespace |
173 | 174 |
174 class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness { | 175 class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness { |
175 public: | 176 public: |
176 MetricsWebContentsObserverTest() : num_errors_(0) {} | 177 MetricsWebContentsObserverTest() : num_errors_(0) {} |
177 | 178 |
178 void SetUp() override { | 179 void SetUp() override { |
179 ChromeRenderViewHostTestHarness::SetUp(); | 180 ChromeRenderViewHostTestHarness::SetUp(); |
180 AttachObserver(); | 181 AttachObserver(); |
181 } | 182 } |
182 | 183 |
183 void NavigateToUntrackedUrl() { | 184 void NavigateToUntrackedUrl() { |
184 content::WebContentsTester::For(web_contents()) | 185 content::WebContentsTester::For(web_contents()) |
185 ->NavigateAndCommit(GURL(url::kAboutBlankURL)); | 186 ->NavigateAndCommit(GURL(url::kAboutBlankURL)); |
186 } | 187 } |
187 | 188 |
188 void SimulateTimingUpdate(const PageLoadTiming& timing) { | 189 void SimulateTimingUpdate(const mojom::PageLoadTiming& timing) { |
189 SimulateTimingUpdate(timing, web_contents()->GetMainFrame()); | 190 SimulateTimingUpdate(timing, web_contents()->GetMainFrame()); |
190 } | 191 } |
191 | 192 |
192 void SimulateTimingUpdate(const PageLoadTiming& timing, | 193 void SimulateTimingUpdate(const mojom::PageLoadTiming& timing, |
193 content::RenderFrameHost* render_frame_host) { | 194 content::RenderFrameHost* render_frame_host) { |
194 observer_->OnTimingUpdated(render_frame_host, timing, PageLoadMetadata()); | 195 observer_->OnTimingUpdated(render_frame_host, timing, |
| 196 mojom::PageLoadMetadata()); |
195 } | 197 } |
196 | 198 |
197 void AttachObserver() { | 199 void AttachObserver() { |
198 embedder_interface_ = | 200 embedder_interface_ = |
199 new TestPageLoadMetricsEmbedderInterface(web_contents()); | 201 new TestPageLoadMetricsEmbedderInterface(web_contents()); |
200 // Owned by the web_contents. Tests must be careful not to call | 202 // Owned by the web_contents. Tests must be careful not to call |
201 // SimulateTimingUpdate after they call DeleteContents() without also | 203 // SimulateTimingUpdate after they call DeleteContents() without also |
202 // calling AttachObserver() again. Otherwise they will use-after-free the | 204 // calling AttachObserver() again. Otherwise they will use-after-free the |
203 // observer_. | 205 // observer_. |
204 observer_ = MetricsWebContentsObserver::CreateForWebContents( | 206 observer_ = MetricsWebContentsObserver::CreateForWebContents( |
(...skipping 10 matching lines...) Expand all Loading... |
215 histogram_tester_.ExpectTotalCount(internal::kErrorEvents, num_errors_); | 217 histogram_tester_.ExpectTotalCount(internal::kErrorEvents, num_errors_); |
216 } | 218 } |
217 | 219 |
218 void CheckNoErrorEvents() { | 220 void CheckNoErrorEvents() { |
219 histogram_tester_.ExpectTotalCount(internal::kErrorEvents, 0); | 221 histogram_tester_.ExpectTotalCount(internal::kErrorEvents, 0); |
220 } | 222 } |
221 | 223 |
222 int CountEmptyCompleteTimingReported() { | 224 int CountEmptyCompleteTimingReported() { |
223 int empty = 0; | 225 int empty = 0; |
224 for (const auto& timing : embedder_interface_->complete_timings()) { | 226 for (const auto& timing : embedder_interface_->complete_timings()) { |
225 if (timing.IsEmpty()) | 227 if (page_load_metrics::IsEmpty(*timing)) |
226 ++empty; | 228 ++empty; |
227 } | 229 } |
228 return empty; | 230 return empty; |
229 } | 231 } |
230 | 232 |
231 const std::vector<PageLoadTiming>& updated_timings() const { | 233 const std::vector<mojom::PageLoadTimingPtr>& updated_timings() const { |
232 return embedder_interface_->updated_timings(); | 234 return embedder_interface_->updated_timings(); |
233 } | 235 } |
234 const std::vector<PageLoadTiming>& complete_timings() const { | 236 const std::vector<mojom::PageLoadTimingPtr>& complete_timings() const { |
235 return embedder_interface_->complete_timings(); | 237 return embedder_interface_->complete_timings(); |
236 } | 238 } |
237 const std::vector<PageLoadTiming>& updated_subframe_timings() const { | 239 const std::vector<mojom::PageLoadTimingPtr>& updated_subframe_timings() |
| 240 const { |
238 return embedder_interface_->updated_subframe_timings(); | 241 return embedder_interface_->updated_subframe_timings(); |
239 } | 242 } |
240 int CountCompleteTimingReported() { return complete_timings().size(); } | 243 int CountCompleteTimingReported() { return complete_timings().size(); } |
241 int CountUpdatedTimingReported() { return updated_timings().size(); } | 244 int CountUpdatedTimingReported() { return updated_timings().size(); } |
242 int CountUpdatedSubFrameTimingReported() { | 245 int CountUpdatedSubFrameTimingReported() { |
243 return updated_subframe_timings().size(); | 246 return updated_subframe_timings().size(); |
244 } | 247 } |
245 | 248 |
246 const std::vector<GURL>& observed_committed_urls_from_on_start() const { | 249 const std::vector<GURL>& observed_committed_urls_from_on_start() const { |
247 return embedder_interface_->observed_committed_urls_from_on_start(); | 250 return embedder_interface_->observed_committed_urls_from_on_start(); |
248 } | 251 } |
249 | 252 |
250 const std::vector<GURL>& completed_filtered_urls() const { | 253 const std::vector<GURL>& completed_filtered_urls() const { |
251 return embedder_interface_->completed_filtered_urls(); | 254 return embedder_interface_->completed_filtered_urls(); |
252 } | 255 } |
253 | 256 |
254 protected: | 257 protected: |
255 base::HistogramTester histogram_tester_; | 258 base::HistogramTester histogram_tester_; |
256 TestPageLoadMetricsEmbedderInterface* embedder_interface_; | 259 TestPageLoadMetricsEmbedderInterface* embedder_interface_; |
257 MetricsWebContentsObserver* observer_; | 260 MetricsWebContentsObserver* observer_; |
258 | 261 |
259 private: | 262 private: |
260 int num_errors_; | 263 int num_errors_; |
261 | 264 |
262 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserverTest); | 265 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserverTest); |
263 }; | 266 }; |
264 | 267 |
265 TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) { | 268 TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) { |
266 PageLoadTiming timing; | 269 mojom::PageLoadTiming timing; |
| 270 page_load_metrics::InitPageLoadTimingForTest(&timing); |
267 timing.navigation_start = base::Time::FromDoubleT(1); | 271 timing.navigation_start = base::Time::FromDoubleT(1); |
268 | 272 |
269 content::WebContentsTester* web_contents_tester = | 273 content::WebContentsTester* web_contents_tester = |
270 content::WebContentsTester::For(web_contents()); | 274 content::WebContentsTester::For(web_contents()); |
271 | 275 |
272 ASSERT_TRUE(observed_committed_urls_from_on_start().empty()); | 276 ASSERT_TRUE(observed_committed_urls_from_on_start().empty()); |
273 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 277 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
274 ASSERT_EQ(1u, observed_committed_urls_from_on_start().size()); | 278 ASSERT_EQ(1u, observed_committed_urls_from_on_start().size()); |
275 ASSERT_TRUE(observed_committed_urls_from_on_start().at(0).is_empty()); | 279 ASSERT_TRUE(observed_committed_urls_from_on_start().at(0).is_empty()); |
276 | 280 |
277 ASSERT_EQ(0, CountUpdatedTimingReported()); | 281 ASSERT_EQ(0, CountUpdatedTimingReported()); |
278 SimulateTimingUpdate(timing); | 282 SimulateTimingUpdate(timing); |
279 ASSERT_EQ(1, CountUpdatedTimingReported()); | 283 ASSERT_EQ(1, CountUpdatedTimingReported()); |
280 ASSERT_EQ(0, CountCompleteTimingReported()); | 284 ASSERT_EQ(0, CountCompleteTimingReported()); |
281 | 285 |
282 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 286 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
283 ASSERT_EQ(1, CountCompleteTimingReported()); | 287 ASSERT_EQ(1, CountCompleteTimingReported()); |
284 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); | 288 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
285 ASSERT_EQ(2u, observed_committed_urls_from_on_start().size()); | 289 ASSERT_EQ(2u, observed_committed_urls_from_on_start().size()); |
286 ASSERT_EQ(kDefaultTestUrl, | 290 ASSERT_EQ(kDefaultTestUrl, |
287 observed_committed_urls_from_on_start().at(1).spec()); | 291 observed_committed_urls_from_on_start().at(1).spec()); |
288 ASSERT_EQ(1, CountUpdatedTimingReported()); | 292 ASSERT_EQ(1, CountUpdatedTimingReported()); |
289 ASSERT_EQ(0, CountUpdatedSubFrameTimingReported()); | 293 ASSERT_EQ(0, CountUpdatedSubFrameTimingReported()); |
290 | 294 |
291 CheckNoErrorEvents(); | 295 CheckNoErrorEvents(); |
292 } | 296 } |
293 | 297 |
294 TEST_F(MetricsWebContentsObserverTest, SubFrame) { | 298 TEST_F(MetricsWebContentsObserverTest, SubFrame) { |
295 PageLoadTiming timing; | 299 mojom::PageLoadTiming timing; |
| 300 page_load_metrics::InitPageLoadTimingForTest(&timing); |
296 timing.navigation_start = base::Time::FromDoubleT(1); | 301 timing.navigation_start = base::Time::FromDoubleT(1); |
297 timing.response_start = base::TimeDelta::FromMilliseconds(10); | 302 timing.response_start = base::TimeDelta::FromMilliseconds(10); |
298 timing.parse_timing.parse_start = base::TimeDelta::FromMilliseconds(20); | 303 timing.parse_timing->parse_start = base::TimeDelta::FromMilliseconds(20); |
299 timing.document_timing.first_layout = base::TimeDelta::FromMilliseconds(30); | 304 timing.document_timing->first_layout = base::TimeDelta::FromMilliseconds(30); |
300 | 305 |
301 content::WebContentsTester* web_contents_tester = | 306 content::WebContentsTester* web_contents_tester = |
302 content::WebContentsTester::For(web_contents()); | 307 content::WebContentsTester::For(web_contents()); |
303 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 308 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
304 SimulateTimingUpdate(timing); | 309 SimulateTimingUpdate(timing); |
305 | 310 |
306 ASSERT_EQ(1, CountUpdatedTimingReported()); | 311 ASSERT_EQ(1, CountUpdatedTimingReported()); |
307 EXPECT_EQ(timing, updated_timings().back()); | 312 EXPECT_TRUE(timing.Equals(*updated_timings().back())); |
308 | 313 |
309 content::RenderFrameHostTester* rfh_tester = | 314 content::RenderFrameHostTester* rfh_tester = |
310 content::RenderFrameHostTester::For(main_rfh()); | 315 content::RenderFrameHostTester::For(main_rfh()); |
311 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); | 316 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); |
312 | 317 |
313 // Dispatch a timing update for the child frame that includes a first paint. | 318 // Dispatch a timing update for the child frame that includes a first paint. |
314 PageLoadTiming subframe_timing; | 319 mojom::PageLoadTiming subframe_timing; |
| 320 page_load_metrics::InitPageLoadTimingForTest(&subframe_timing); |
315 subframe_timing.navigation_start = base::Time::FromDoubleT(2); | 321 subframe_timing.navigation_start = base::Time::FromDoubleT(2); |
316 subframe_timing.response_start = base::TimeDelta::FromMilliseconds(10); | 322 subframe_timing.response_start = base::TimeDelta::FromMilliseconds(10); |
317 subframe_timing.parse_timing.parse_start = | 323 subframe_timing.parse_timing->parse_start = |
318 base::TimeDelta::FromMilliseconds(20); | 324 base::TimeDelta::FromMilliseconds(20); |
319 subframe_timing.document_timing.first_layout = | 325 subframe_timing.document_timing->first_layout = |
320 base::TimeDelta::FromMilliseconds(30); | 326 base::TimeDelta::FromMilliseconds(30); |
321 subframe_timing.paint_timing.first_paint = | 327 subframe_timing.paint_timing->first_paint = |
322 base::TimeDelta::FromMilliseconds(40); | 328 base::TimeDelta::FromMilliseconds(40); |
323 content::RenderFrameHostTester* subframe_tester = | 329 content::RenderFrameHostTester* subframe_tester = |
324 content::RenderFrameHostTester::For(subframe); | 330 content::RenderFrameHostTester::For(subframe); |
325 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); | 331 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); |
326 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); | 332 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); |
327 SimulateTimingUpdate(subframe_timing, subframe); | 333 SimulateTimingUpdate(subframe_timing, subframe); |
328 subframe_tester->SimulateNavigationStop(); | 334 subframe_tester->SimulateNavigationStop(); |
329 | 335 |
330 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); | 336 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
331 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); | 337 EXPECT_TRUE(subframe_timing.Equals(*updated_subframe_timings().back())); |
332 | 338 |
333 // The subframe update which included a paint should have also triggered | 339 // The subframe update which included a paint should have also triggered |
334 // a main frame update, which includes a first paint. | 340 // a main frame update, which includes a first paint. |
335 ASSERT_EQ(2, CountUpdatedTimingReported()); | 341 ASSERT_EQ(2, CountUpdatedTimingReported()); |
336 EXPECT_NE(timing, updated_timings().back()); | 342 EXPECT_FALSE(timing.Equals(*updated_timings().back())); |
337 EXPECT_TRUE(updated_timings().back().paint_timing.first_paint); | 343 EXPECT_TRUE(updated_timings().back()->paint_timing->first_paint); |
338 | 344 |
339 // Navigate again to see if the timing updated for a subframe message. | 345 // Navigate again to see if the timing updated for a subframe message. |
340 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 346 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
341 | 347 |
342 ASSERT_EQ(1, CountCompleteTimingReported()); | 348 ASSERT_EQ(1, CountCompleteTimingReported()); |
343 ASSERT_EQ(2, CountUpdatedTimingReported()); | 349 ASSERT_EQ(2, CountUpdatedTimingReported()); |
344 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); | 350 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
345 | 351 |
346 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); | 352 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
347 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); | 353 EXPECT_TRUE(subframe_timing.Equals(*updated_subframe_timings().back())); |
348 | 354 |
349 CheckNoErrorEvents(); | 355 CheckNoErrorEvents(); |
350 } | 356 } |
351 | 357 |
352 TEST_F(MetricsWebContentsObserverTest, SameDocumentNoTrigger) { | 358 TEST_F(MetricsWebContentsObserverTest, SameDocumentNoTrigger) { |
353 PageLoadTiming timing; | 359 mojom::PageLoadTiming timing; |
| 360 page_load_metrics::InitPageLoadTimingForTest(&timing); |
354 timing.navigation_start = base::Time::FromDoubleT(1); | 361 timing.navigation_start = base::Time::FromDoubleT(1); |
355 | 362 |
356 content::WebContentsTester* web_contents_tester = | 363 content::WebContentsTester* web_contents_tester = |
357 content::WebContentsTester::For(web_contents()); | 364 content::WebContentsTester::For(web_contents()); |
358 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 365 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
359 ASSERT_EQ(0, CountUpdatedTimingReported()); | 366 ASSERT_EQ(0, CountUpdatedTimingReported()); |
360 SimulateTimingUpdate(timing); | 367 SimulateTimingUpdate(timing); |
361 ASSERT_EQ(1, CountUpdatedTimingReported()); | 368 ASSERT_EQ(1, CountUpdatedTimingReported()); |
362 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrlAnchor)); | 369 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrlAnchor)); |
363 // Send the same timing update. The original tracker for kDefaultTestUrl | 370 // Send the same timing update. The original tracker for kDefaultTestUrl |
364 // should dedup the update, and the tracker for kDefaultTestUrlAnchor should | 371 // should dedup the update, and the tracker for kDefaultTestUrlAnchor should |
365 // have been destroyed as a result of its being a same page navigation, so | 372 // have been destroyed as a result of its being a same page navigation, so |
366 // CountUpdatedTimingReported() should continue to return 1. | 373 // CountUpdatedTimingReported() should continue to return 1. |
367 SimulateTimingUpdate(timing); | 374 SimulateTimingUpdate(timing); |
368 | 375 |
369 ASSERT_EQ(1, CountUpdatedTimingReported()); | 376 ASSERT_EQ(1, CountUpdatedTimingReported()); |
370 ASSERT_EQ(0, CountCompleteTimingReported()); | 377 ASSERT_EQ(0, CountCompleteTimingReported()); |
371 | 378 |
372 // Navigate again to force histogram logging. | 379 // Navigate again to force histogram logging. |
373 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 380 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
374 | 381 |
375 // A same page navigation shouldn't trigger logging UMA for the original. | 382 // A same page navigation shouldn't trigger logging UMA for the original. |
376 ASSERT_EQ(1, CountUpdatedTimingReported()); | 383 ASSERT_EQ(1, CountUpdatedTimingReported()); |
377 ASSERT_EQ(1, CountCompleteTimingReported()); | 384 ASSERT_EQ(1, CountCompleteTimingReported()); |
378 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); | 385 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
379 CheckNoErrorEvents(); | 386 CheckNoErrorEvents(); |
380 } | 387 } |
381 | 388 |
382 TEST_F(MetricsWebContentsObserverTest, DontLogNewTabPage) { | 389 TEST_F(MetricsWebContentsObserverTest, DontLogNewTabPage) { |
383 PageLoadTiming timing; | 390 mojom::PageLoadTiming timing; |
| 391 page_load_metrics::InitPageLoadTimingForTest(&timing); |
384 timing.navigation_start = base::Time::FromDoubleT(1); | 392 timing.navigation_start = base::Time::FromDoubleT(1); |
385 | 393 |
386 content::WebContentsTester* web_contents_tester = | 394 content::WebContentsTester* web_contents_tester = |
387 content::WebContentsTester::For(web_contents()); | 395 content::WebContentsTester::For(web_contents()); |
388 embedder_interface_->set_is_ntp(true); | 396 embedder_interface_->set_is_ntp(true); |
389 | 397 |
390 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 398 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
391 SimulateTimingUpdate(timing); | 399 SimulateTimingUpdate(timing); |
392 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 400 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
393 ASSERT_EQ(0, CountUpdatedTimingReported()); | 401 ASSERT_EQ(0, CountUpdatedTimingReported()); |
394 ASSERT_EQ(0, CountCompleteTimingReported()); | 402 ASSERT_EQ(0, CountCompleteTimingReported()); |
395 CheckErrorEvent(ERR_IPC_WITH_NO_RELEVANT_LOAD, 1); | 403 CheckErrorEvent(ERR_IPC_WITH_NO_RELEVANT_LOAD, 1); |
396 CheckTotalErrorEvents(); | 404 CheckTotalErrorEvents(); |
397 } | 405 } |
398 | 406 |
399 TEST_F(MetricsWebContentsObserverTest, DontLogIrrelevantNavigation) { | 407 TEST_F(MetricsWebContentsObserverTest, DontLogIrrelevantNavigation) { |
400 PageLoadTiming timing; | 408 mojom::PageLoadTiming timing; |
| 409 page_load_metrics::InitPageLoadTimingForTest(&timing); |
401 timing.navigation_start = base::Time::FromDoubleT(10); | 410 timing.navigation_start = base::Time::FromDoubleT(10); |
402 | 411 |
403 content::WebContentsTester* web_contents_tester = | 412 content::WebContentsTester* web_contents_tester = |
404 content::WebContentsTester::For(web_contents()); | 413 content::WebContentsTester::For(web_contents()); |
405 | 414 |
406 GURL about_blank_url = GURL("about:blank"); | 415 GURL about_blank_url = GURL("about:blank"); |
407 web_contents_tester->NavigateAndCommit(about_blank_url); | 416 web_contents_tester->NavigateAndCommit(about_blank_url); |
408 SimulateTimingUpdate(timing); | 417 SimulateTimingUpdate(timing); |
409 ASSERT_EQ(0, CountUpdatedTimingReported()); | 418 ASSERT_EQ(0, CountUpdatedTimingReported()); |
410 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 419 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
411 ASSERT_EQ(0, CountUpdatedTimingReported()); | 420 ASSERT_EQ(0, CountUpdatedTimingReported()); |
412 ASSERT_EQ(0, CountCompleteTimingReported()); | 421 ASSERT_EQ(0, CountCompleteTimingReported()); |
413 | 422 |
414 CheckErrorEvent(ERR_IPC_FROM_BAD_URL_SCHEME, 1); | 423 CheckErrorEvent(ERR_IPC_FROM_BAD_URL_SCHEME, 1); |
415 CheckErrorEvent(ERR_IPC_WITH_NO_RELEVANT_LOAD, 1); | 424 CheckErrorEvent(ERR_IPC_WITH_NO_RELEVANT_LOAD, 1); |
416 CheckTotalErrorEvents(); | 425 CheckTotalErrorEvents(); |
417 } | 426 } |
418 | 427 |
419 TEST_F(MetricsWebContentsObserverTest, EmptyTimingError) { | 428 TEST_F(MetricsWebContentsObserverTest, EmptyTimingError) { |
420 PageLoadTiming timing; | 429 mojom::PageLoadTiming timing; |
| 430 page_load_metrics::InitPageLoadTimingForTest(&timing); |
421 | 431 |
422 content::WebContentsTester* web_contents_tester = | 432 content::WebContentsTester* web_contents_tester = |
423 content::WebContentsTester::For(web_contents()); | 433 content::WebContentsTester::For(web_contents()); |
424 | 434 |
425 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 435 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
426 SimulateTimingUpdate(timing); | 436 SimulateTimingUpdate(timing); |
427 ASSERT_EQ(0, CountUpdatedTimingReported()); | 437 ASSERT_EQ(0, CountUpdatedTimingReported()); |
428 NavigateToUntrackedUrl(); | 438 NavigateToUntrackedUrl(); |
429 ASSERT_EQ(0, CountUpdatedTimingReported()); | 439 ASSERT_EQ(0, CountUpdatedTimingReported()); |
430 ASSERT_EQ(1, CountCompleteTimingReported()); | 440 ASSERT_EQ(1, CountCompleteTimingReported()); |
431 | 441 |
432 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING, 1); | 442 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING, 1); |
433 CheckErrorEvent(ERR_NO_IPCS_RECEIVED, 1); | 443 CheckErrorEvent(ERR_NO_IPCS_RECEIVED, 1); |
434 CheckTotalErrorEvents(); | 444 CheckTotalErrorEvents(); |
435 | 445 |
436 histogram_tester_.ExpectTotalCount( | 446 histogram_tester_.ExpectTotalCount( |
437 page_load_metrics::internal::kPageLoadTimingStatus, 1); | 447 page_load_metrics::internal::kPageLoadTimingStatus, 1); |
438 histogram_tester_.ExpectBucketCount( | 448 histogram_tester_.ExpectBucketCount( |
439 page_load_metrics::internal::kPageLoadTimingStatus, | 449 page_load_metrics::internal::kPageLoadTimingStatus, |
440 page_load_metrics::internal::INVALID_EMPTY_TIMING, 1); | 450 page_load_metrics::internal::INVALID_EMPTY_TIMING, 1); |
441 } | 451 } |
442 | 452 |
443 TEST_F(MetricsWebContentsObserverTest, NullNavigationStartError) { | 453 TEST_F(MetricsWebContentsObserverTest, NullNavigationStartError) { |
444 PageLoadTiming timing; | 454 mojom::PageLoadTiming timing; |
445 timing.parse_timing.parse_start = base::TimeDelta::FromMilliseconds(1); | 455 page_load_metrics::InitPageLoadTimingForTest(&timing); |
| 456 timing.parse_timing->parse_start = base::TimeDelta::FromMilliseconds(1); |
446 | 457 |
447 content::WebContentsTester* web_contents_tester = | 458 content::WebContentsTester* web_contents_tester = |
448 content::WebContentsTester::For(web_contents()); | 459 content::WebContentsTester::For(web_contents()); |
449 | 460 |
450 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 461 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
451 SimulateTimingUpdate(timing); | 462 SimulateTimingUpdate(timing); |
452 ASSERT_EQ(0, CountUpdatedTimingReported()); | 463 ASSERT_EQ(0, CountUpdatedTimingReported()); |
453 NavigateToUntrackedUrl(); | 464 NavigateToUntrackedUrl(); |
454 ASSERT_EQ(0, CountUpdatedTimingReported()); | 465 ASSERT_EQ(0, CountUpdatedTimingReported()); |
455 ASSERT_EQ(1, CountCompleteTimingReported()); | 466 ASSERT_EQ(1, CountCompleteTimingReported()); |
456 | 467 |
457 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING, 1); | 468 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING, 1); |
458 CheckErrorEvent(ERR_NO_IPCS_RECEIVED, 1); | 469 CheckErrorEvent(ERR_NO_IPCS_RECEIVED, 1); |
459 CheckTotalErrorEvents(); | 470 CheckTotalErrorEvents(); |
460 | 471 |
461 histogram_tester_.ExpectTotalCount( | 472 histogram_tester_.ExpectTotalCount( |
462 page_load_metrics::internal::kPageLoadTimingStatus, 1); | 473 page_load_metrics::internal::kPageLoadTimingStatus, 1); |
463 histogram_tester_.ExpectBucketCount( | 474 histogram_tester_.ExpectBucketCount( |
464 page_load_metrics::internal::kPageLoadTimingStatus, | 475 page_load_metrics::internal::kPageLoadTimingStatus, |
465 page_load_metrics::internal::INVALID_NULL_NAVIGATION_START, 1); | 476 page_load_metrics::internal::INVALID_NULL_NAVIGATION_START, 1); |
466 } | 477 } |
467 | 478 |
468 TEST_F(MetricsWebContentsObserverTest, TimingOrderError) { | 479 TEST_F(MetricsWebContentsObserverTest, TimingOrderError) { |
469 PageLoadTiming timing; | 480 mojom::PageLoadTiming timing; |
| 481 page_load_metrics::InitPageLoadTimingForTest(&timing); |
470 timing.navigation_start = base::Time::FromDoubleT(1); | 482 timing.navigation_start = base::Time::FromDoubleT(1); |
471 timing.parse_timing.parse_stop = base::TimeDelta::FromMilliseconds(1); | 483 timing.parse_timing->parse_stop = base::TimeDelta::FromMilliseconds(1); |
472 | 484 |
473 content::WebContentsTester* web_contents_tester = | 485 content::WebContentsTester* web_contents_tester = |
474 content::WebContentsTester::For(web_contents()); | 486 content::WebContentsTester::For(web_contents()); |
475 | 487 |
476 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 488 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
477 SimulateTimingUpdate(timing); | 489 SimulateTimingUpdate(timing); |
478 ASSERT_EQ(0, CountUpdatedTimingReported()); | 490 ASSERT_EQ(0, CountUpdatedTimingReported()); |
479 NavigateToUntrackedUrl(); | 491 NavigateToUntrackedUrl(); |
480 ASSERT_EQ(0, CountUpdatedTimingReported()); | 492 ASSERT_EQ(0, CountUpdatedTimingReported()); |
481 ASSERT_EQ(1, CountCompleteTimingReported()); | 493 ASSERT_EQ(1, CountCompleteTimingReported()); |
482 | 494 |
483 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING, 1); | 495 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING, 1); |
484 CheckErrorEvent(ERR_NO_IPCS_RECEIVED, 1); | 496 CheckErrorEvent(ERR_NO_IPCS_RECEIVED, 1); |
485 CheckTotalErrorEvents(); | 497 CheckTotalErrorEvents(); |
486 | 498 |
487 histogram_tester_.ExpectTotalCount( | 499 histogram_tester_.ExpectTotalCount( |
488 page_load_metrics::internal::kPageLoadTimingStatus, 1); | 500 page_load_metrics::internal::kPageLoadTimingStatus, 1); |
489 histogram_tester_.ExpectBucketCount( | 501 histogram_tester_.ExpectBucketCount( |
490 page_load_metrics::internal::kPageLoadTimingStatus, | 502 page_load_metrics::internal::kPageLoadTimingStatus, |
491 page_load_metrics::internal::INVALID_ORDER_PARSE_START_PARSE_STOP, 1); | 503 page_load_metrics::internal::INVALID_ORDER_PARSE_START_PARSE_STOP, 1); |
492 } | 504 } |
493 | 505 |
494 TEST_F(MetricsWebContentsObserverTest, BadIPC) { | 506 TEST_F(MetricsWebContentsObserverTest, BadIPC) { |
495 PageLoadTiming timing; | 507 mojom::PageLoadTiming timing; |
| 508 page_load_metrics::InitPageLoadTimingForTest(&timing); |
496 timing.navigation_start = base::Time::FromDoubleT(10); | 509 timing.navigation_start = base::Time::FromDoubleT(10); |
497 PageLoadTiming timing2; | 510 mojom::PageLoadTiming timing2; |
| 511 page_load_metrics::InitPageLoadTimingForTest(&timing2); |
498 timing2.navigation_start = base::Time::FromDoubleT(100); | 512 timing2.navigation_start = base::Time::FromDoubleT(100); |
499 | 513 |
500 content::WebContentsTester* web_contents_tester = | 514 content::WebContentsTester* web_contents_tester = |
501 content::WebContentsTester::For(web_contents()); | 515 content::WebContentsTester::For(web_contents()); |
502 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 516 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
503 | 517 |
504 SimulateTimingUpdate(timing); | 518 SimulateTimingUpdate(timing); |
505 ASSERT_EQ(1, CountUpdatedTimingReported()); | 519 ASSERT_EQ(1, CountUpdatedTimingReported()); |
506 SimulateTimingUpdate(timing2); | 520 SimulateTimingUpdate(timing2); |
507 ASSERT_EQ(1, CountUpdatedTimingReported()); | 521 ASSERT_EQ(1, CountUpdatedTimingReported()); |
508 | 522 |
509 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT, 1); | 523 CheckErrorEvent(ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT, 1); |
510 CheckTotalErrorEvents(); | 524 CheckTotalErrorEvents(); |
511 } | 525 } |
512 | 526 |
513 TEST_F(MetricsWebContentsObserverTest, ObservePartialNavigation) { | 527 TEST_F(MetricsWebContentsObserverTest, ObservePartialNavigation) { |
514 // Reset the state of the tests, and attach the MetricsWebContentsObserver in | 528 // Reset the state of the tests, and attach the MetricsWebContentsObserver in |
515 // the middle of a navigation. This tests that the class is robust to only | 529 // the middle of a navigation. This tests that the class is robust to only |
516 // observing some of a navigation. | 530 // observing some of a navigation. |
517 DeleteContents(); | 531 DeleteContents(); |
518 SetContents(CreateTestWebContents()); | 532 SetContents(CreateTestWebContents()); |
519 | 533 |
520 PageLoadTiming timing; | 534 mojom::PageLoadTiming timing; |
| 535 page_load_metrics::InitPageLoadTimingForTest(&timing); |
521 timing.navigation_start = base::Time::FromDoubleT(10); | 536 timing.navigation_start = base::Time::FromDoubleT(10); |
522 | 537 |
523 content::WebContentsTester* web_contents_tester = | 538 content::WebContentsTester* web_contents_tester = |
524 content::WebContentsTester::For(web_contents()); | 539 content::WebContentsTester::For(web_contents()); |
525 content::RenderFrameHostTester* rfh_tester = | 540 content::RenderFrameHostTester* rfh_tester = |
526 content::RenderFrameHostTester::For(main_rfh()); | 541 content::RenderFrameHostTester::For(main_rfh()); |
527 | 542 |
528 // Start the navigation, then start observing the web contents. This used to | 543 // Start the navigation, then start observing the web contents. This used to |
529 // crash us. Make sure we bail out and don't log histograms. | 544 // crash us. Make sure we bail out and don't log histograms. |
530 web_contents_tester->StartNavigation(GURL(kDefaultTestUrl)); | 545 web_contents_tester->StartNavigation(GURL(kDefaultTestUrl)); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 completed_filtered_urls()); | 719 completed_filtered_urls()); |
705 | 720 |
706 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 721 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
707 ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl), GURL(kDefaultTestUrl2)}), | 722 ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl), GURL(kDefaultTestUrl2)}), |
708 completed_filtered_urls()); | 723 completed_filtered_urls()); |
709 } | 724 } |
710 | 725 |
711 // We buffer cross frame timings in order to provide a consistent view of | 726 // We buffer cross frame timings in order to provide a consistent view of |
712 // timing data to observers. See crbug.com/722860 for more. | 727 // timing data to observers. See crbug.com/722860 for more. |
713 TEST_F(MetricsWebContentsObserverTest, OutOfOrderCrossFrameTiming) { | 728 TEST_F(MetricsWebContentsObserverTest, OutOfOrderCrossFrameTiming) { |
714 PageLoadTiming timing; | 729 mojom::PageLoadTiming timing; |
| 730 page_load_metrics::InitPageLoadTimingForTest(&timing); |
715 timing.navigation_start = base::Time::FromDoubleT(1); | 731 timing.navigation_start = base::Time::FromDoubleT(1); |
716 timing.response_start = base::TimeDelta::FromMilliseconds(10); | 732 timing.response_start = base::TimeDelta::FromMilliseconds(10); |
717 | 733 |
718 content::WebContentsTester* web_contents_tester = | 734 content::WebContentsTester* web_contents_tester = |
719 content::WebContentsTester::For(web_contents()); | 735 content::WebContentsTester::For(web_contents()); |
720 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 736 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
721 SimulateTimingUpdate(timing); | 737 SimulateTimingUpdate(timing); |
722 | 738 |
723 ASSERT_EQ(1, CountUpdatedTimingReported()); | 739 ASSERT_EQ(1, CountUpdatedTimingReported()); |
724 EXPECT_EQ(timing, updated_timings().back()); | 740 EXPECT_TRUE(timing.Equals(*updated_timings().back())); |
725 | 741 |
726 content::RenderFrameHostTester* rfh_tester = | 742 content::RenderFrameHostTester* rfh_tester = |
727 content::RenderFrameHostTester::For(main_rfh()); | 743 content::RenderFrameHostTester::For(main_rfh()); |
728 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); | 744 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); |
729 | 745 |
730 // Dispatch a timing update for the child frame that includes a first paint. | 746 // Dispatch a timing update for the child frame that includes a first paint. |
731 PageLoadTiming subframe_timing; | 747 mojom::PageLoadTiming subframe_timing; |
| 748 page_load_metrics::InitPageLoadTimingForTest(&subframe_timing); |
732 subframe_timing.navigation_start = base::Time::FromDoubleT(2); | 749 subframe_timing.navigation_start = base::Time::FromDoubleT(2); |
733 subframe_timing.response_start = base::TimeDelta::FromMilliseconds(10); | 750 subframe_timing.response_start = base::TimeDelta::FromMilliseconds(10); |
734 subframe_timing.parse_timing.parse_start = | 751 subframe_timing.parse_timing->parse_start = |
735 base::TimeDelta::FromMilliseconds(20); | 752 base::TimeDelta::FromMilliseconds(20); |
736 subframe_timing.document_timing.first_layout = | 753 subframe_timing.document_timing->first_layout = |
737 base::TimeDelta::FromMilliseconds(30); | 754 base::TimeDelta::FromMilliseconds(30); |
738 subframe_timing.paint_timing.first_paint = | 755 subframe_timing.paint_timing->first_paint = |
739 base::TimeDelta::FromMilliseconds(40); | 756 base::TimeDelta::FromMilliseconds(40); |
740 content::RenderFrameHostTester* subframe_tester = | 757 content::RenderFrameHostTester* subframe_tester = |
741 content::RenderFrameHostTester::For(subframe); | 758 content::RenderFrameHostTester::For(subframe); |
742 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); | 759 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); |
743 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); | 760 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); |
744 SimulateTimingUpdate(subframe_timing, subframe); | 761 SimulateTimingUpdate(subframe_timing, subframe); |
745 subframe_tester->SimulateNavigationStop(); | 762 subframe_tester->SimulateNavigationStop(); |
746 | 763 |
747 // Though a first paint was dispatched in the child, it should not yet be | 764 // Though a first paint was dispatched in the child, it should not yet be |
748 // reflected as an updated timing in the main frame, since the main frame | 765 // reflected as an updated timing in the main frame, since the main frame |
749 // hasn't received updates for required earlier events such as parse_start and | 766 // hasn't received updates for required earlier events such as parse_start and |
750 // first_layout. | 767 // first_layout. |
751 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); | 768 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
752 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); | 769 EXPECT_TRUE(subframe_timing.Equals(*updated_subframe_timings().back())); |
753 ASSERT_EQ(1, CountUpdatedTimingReported()); | 770 ASSERT_EQ(1, CountUpdatedTimingReported()); |
754 EXPECT_EQ(timing, updated_timings().back()); | 771 EXPECT_TRUE(timing.Equals(*updated_timings().back())); |
755 | 772 |
756 // Dispatch the parse_start event in the parent. We should still not observe | 773 // Dispatch the parse_start event in the parent. We should still not observe |
757 // a first paint main frame update, since we don't yet have a first_layout. | 774 // a first paint main frame update, since we don't yet have a first_layout. |
758 timing.parse_timing.parse_start = base::TimeDelta::FromMilliseconds(20); | 775 timing.parse_timing->parse_start = base::TimeDelta::FromMilliseconds(20); |
759 SimulateTimingUpdate(timing); | 776 SimulateTimingUpdate(timing); |
760 ASSERT_EQ(1, CountUpdatedTimingReported()); | 777 ASSERT_EQ(1, CountUpdatedTimingReported()); |
761 EXPECT_NE(timing, updated_timings().back()); | 778 EXPECT_FALSE(timing.Equals(*updated_timings().back())); |
762 EXPECT_FALSE(updated_timings().back().parse_timing.parse_start); | 779 EXPECT_FALSE(updated_timings().back()->parse_timing->parse_start); |
763 EXPECT_FALSE(updated_timings().back().paint_timing.first_paint); | 780 EXPECT_FALSE(updated_timings().back()->paint_timing->first_paint); |
764 | 781 |
765 // Dispatch a first_layout in the parent. We should now unbuffer the first | 782 // Dispatch a first_layout in the parent. We should now unbuffer the first |
766 // paint main frame update and receive a main frame update with a first paint | 783 // paint main frame update and receive a main frame update with a first paint |
767 // value. | 784 // value. |
768 timing.document_timing.first_layout = base::TimeDelta::FromMilliseconds(30); | 785 timing.document_timing->first_layout = base::TimeDelta::FromMilliseconds(30); |
769 SimulateTimingUpdate(timing); | 786 SimulateTimingUpdate(timing); |
770 ASSERT_EQ(2, CountUpdatedTimingReported()); | 787 ASSERT_EQ(2, CountUpdatedTimingReported()); |
771 EXPECT_NE(timing, updated_timings().back()); | 788 EXPECT_FALSE(timing.Equals(*updated_timings().back())); |
772 EXPECT_EQ(updated_timings().back().parse_timing, timing.parse_timing); | 789 EXPECT_TRUE( |
773 EXPECT_EQ(updated_timings().back().document_timing, timing.document_timing); | 790 updated_timings().back()->parse_timing->Equals(*timing.parse_timing)); |
774 EXPECT_NE(updated_timings().back().paint_timing, timing.paint_timing); | 791 EXPECT_TRUE(updated_timings().back()->document_timing->Equals( |
775 EXPECT_TRUE(updated_timings().back().paint_timing.first_paint); | 792 *timing.document_timing)); |
| 793 EXPECT_FALSE( |
| 794 updated_timings().back()->paint_timing->Equals(*timing.paint_timing)); |
| 795 EXPECT_TRUE(updated_timings().back()->paint_timing->first_paint); |
776 | 796 |
777 // Navigate again to see if the timing updated for a subframe message. | 797 // Navigate again to see if the timing updated for a subframe message. |
778 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 798 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
779 | 799 |
780 ASSERT_EQ(1, CountCompleteTimingReported()); | 800 ASSERT_EQ(1, CountCompleteTimingReported()); |
781 ASSERT_EQ(2, CountUpdatedTimingReported()); | 801 ASSERT_EQ(2, CountUpdatedTimingReported()); |
782 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); | 802 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
783 | 803 |
784 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); | 804 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
785 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); | 805 EXPECT_TRUE(subframe_timing.Equals(*updated_subframe_timings().back())); |
786 | 806 |
787 CheckNoErrorEvents(); | 807 CheckNoErrorEvents(); |
788 } | 808 } |
789 | 809 |
790 } // namespace page_load_metrics | 810 } // namespace page_load_metrics |
OLD | NEW |