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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 observed_committed_urls_from_on_start().at(1).spec()); | 287 observed_committed_urls_from_on_start().at(1).spec()); |
288 ASSERT_EQ(1, CountUpdatedTimingReported()); | 288 ASSERT_EQ(1, CountUpdatedTimingReported()); |
289 ASSERT_EQ(0, CountUpdatedSubFrameTimingReported()); | 289 ASSERT_EQ(0, CountUpdatedSubFrameTimingReported()); |
290 | 290 |
291 CheckNoErrorEvents(); | 291 CheckNoErrorEvents(); |
292 } | 292 } |
293 | 293 |
294 TEST_F(MetricsWebContentsObserverTest, SubFrame) { | 294 TEST_F(MetricsWebContentsObserverTest, SubFrame) { |
295 PageLoadTiming timing; | 295 PageLoadTiming timing; |
296 timing.navigation_start = base::Time::FromDoubleT(1); | 296 timing.navigation_start = base::Time::FromDoubleT(1); |
| 297 timing.response_start = base::TimeDelta::FromMilliseconds(10); |
| 298 timing.parse_timing.parse_start = base::TimeDelta::FromMilliseconds(20); |
| 299 timing.document_timing.first_layout = base::TimeDelta::FromMilliseconds(30); |
297 | 300 |
298 content::WebContentsTester* web_contents_tester = | 301 content::WebContentsTester* web_contents_tester = |
299 content::WebContentsTester::For(web_contents()); | 302 content::WebContentsTester::For(web_contents()); |
300 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 303 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
301 SimulateTimingUpdate(timing); | 304 SimulateTimingUpdate(timing); |
302 | 305 |
| 306 ASSERT_EQ(1, CountUpdatedTimingReported()); |
| 307 EXPECT_EQ(timing, updated_timings().back()); |
| 308 |
303 content::RenderFrameHostTester* rfh_tester = | 309 content::RenderFrameHostTester* rfh_tester = |
304 content::RenderFrameHostTester::For(main_rfh()); | 310 content::RenderFrameHostTester::For(main_rfh()); |
305 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); | 311 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); |
306 | 312 |
| 313 // Dispatch a timing update for the child frame that includes a first paint. |
307 PageLoadTiming subframe_timing; | 314 PageLoadTiming subframe_timing; |
308 subframe_timing.navigation_start = base::Time::FromDoubleT(2); | 315 subframe_timing.navigation_start = base::Time::FromDoubleT(2); |
| 316 subframe_timing.response_start = base::TimeDelta::FromMilliseconds(10); |
| 317 subframe_timing.parse_timing.parse_start = |
| 318 base::TimeDelta::FromMilliseconds(20); |
| 319 subframe_timing.document_timing.first_layout = |
| 320 base::TimeDelta::FromMilliseconds(30); |
| 321 subframe_timing.paint_timing.first_paint = |
| 322 base::TimeDelta::FromMilliseconds(40); |
309 content::RenderFrameHostTester* subframe_tester = | 323 content::RenderFrameHostTester* subframe_tester = |
310 content::RenderFrameHostTester::For(subframe); | 324 content::RenderFrameHostTester::For(subframe); |
311 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); | 325 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); |
312 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); | 326 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); |
313 SimulateTimingUpdate(subframe_timing, subframe); | 327 SimulateTimingUpdate(subframe_timing, subframe); |
314 subframe_tester->SimulateNavigationStop(); | 328 subframe_tester->SimulateNavigationStop(); |
315 | 329 |
| 330 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
| 331 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); |
| 332 |
| 333 // The subframe update which included a paint should have also triggered |
| 334 // a main frame update, which includes a first paint. |
| 335 ASSERT_EQ(2, CountUpdatedTimingReported()); |
| 336 EXPECT_NE(timing, updated_timings().back()); |
| 337 EXPECT_TRUE(updated_timings().back().paint_timing.first_paint); |
| 338 |
316 // Navigate again to see if the timing updated for a subframe message. | 339 // Navigate again to see if the timing updated for a subframe message. |
317 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 340 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
318 | 341 |
319 ASSERT_EQ(1, CountCompleteTimingReported()); | 342 ASSERT_EQ(1, CountCompleteTimingReported()); |
320 ASSERT_EQ(1, CountUpdatedTimingReported()); | 343 ASSERT_EQ(2, CountUpdatedTimingReported()); |
321 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); | 344 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
322 EXPECT_EQ(timing, updated_timings().at(0)); | |
323 | 345 |
324 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); | 346 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
325 EXPECT_EQ(subframe_timing, updated_subframe_timings().at(0)); | 347 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); |
326 | 348 |
327 CheckNoErrorEvents(); | 349 CheckNoErrorEvents(); |
328 } | 350 } |
329 | 351 |
330 TEST_F(MetricsWebContentsObserverTest, SameDocumentNoTrigger) { | 352 TEST_F(MetricsWebContentsObserverTest, SameDocumentNoTrigger) { |
331 PageLoadTiming timing; | 353 PageLoadTiming timing; |
332 timing.navigation_start = base::Time::FromDoubleT(1); | 354 timing.navigation_start = base::Time::FromDoubleT(1); |
333 | 355 |
334 content::WebContentsTester* web_contents_tester = | 356 content::WebContentsTester* web_contents_tester = |
335 content::WebContentsTester::For(web_contents()); | 357 content::WebContentsTester::For(web_contents()); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 | 701 |
680 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); | 702 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
681 ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl)}), | 703 ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl)}), |
682 completed_filtered_urls()); | 704 completed_filtered_urls()); |
683 | 705 |
684 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 706 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
685 ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl), GURL(kDefaultTestUrl2)}), | 707 ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl), GURL(kDefaultTestUrl2)}), |
686 completed_filtered_urls()); | 708 completed_filtered_urls()); |
687 } | 709 } |
688 | 710 |
| 711 // We buffer cross frame timings in order to provide a consistent view of |
| 712 // timing data to observers. See crbug.com/722860 for more. |
| 713 TEST_F(MetricsWebContentsObserverTest, OutOfOrderCrossFrameTiming) { |
| 714 PageLoadTiming timing; |
| 715 timing.navigation_start = base::Time::FromDoubleT(1); |
| 716 timing.response_start = base::TimeDelta::FromMilliseconds(10); |
| 717 |
| 718 content::WebContentsTester* web_contents_tester = |
| 719 content::WebContentsTester::For(web_contents()); |
| 720 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
| 721 SimulateTimingUpdate(timing); |
| 722 |
| 723 ASSERT_EQ(1, CountUpdatedTimingReported()); |
| 724 EXPECT_EQ(timing, updated_timings().back()); |
| 725 |
| 726 content::RenderFrameHostTester* rfh_tester = |
| 727 content::RenderFrameHostTester::For(main_rfh()); |
| 728 content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); |
| 729 |
| 730 // Dispatch a timing update for the child frame that includes a first paint. |
| 731 PageLoadTiming subframe_timing; |
| 732 subframe_timing.navigation_start = base::Time::FromDoubleT(2); |
| 733 subframe_timing.response_start = base::TimeDelta::FromMilliseconds(10); |
| 734 subframe_timing.parse_timing.parse_start = |
| 735 base::TimeDelta::FromMilliseconds(20); |
| 736 subframe_timing.document_timing.first_layout = |
| 737 base::TimeDelta::FromMilliseconds(30); |
| 738 subframe_timing.paint_timing.first_paint = |
| 739 base::TimeDelta::FromMilliseconds(40); |
| 740 content::RenderFrameHostTester* subframe_tester = |
| 741 content::RenderFrameHostTester::For(subframe); |
| 742 subframe_tester->SimulateNavigationStart(GURL(kDefaultTestUrl2)); |
| 743 subframe_tester->SimulateNavigationCommit(GURL(kDefaultTestUrl2)); |
| 744 SimulateTimingUpdate(subframe_timing, subframe); |
| 745 subframe_tester->SimulateNavigationStop(); |
| 746 |
| 747 // 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 |
| 749 // hasn't received updates for required earlier events such as parse_start and |
| 750 // first_layout. |
| 751 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
| 752 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); |
| 753 ASSERT_EQ(1, CountUpdatedTimingReported()); |
| 754 EXPECT_EQ(timing, updated_timings().back()); |
| 755 |
| 756 // 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. |
| 758 timing.parse_timing.parse_start = base::TimeDelta::FromMilliseconds(20); |
| 759 SimulateTimingUpdate(timing); |
| 760 ASSERT_EQ(1, CountUpdatedTimingReported()); |
| 761 EXPECT_NE(timing, updated_timings().back()); |
| 762 EXPECT_FALSE(updated_timings().back().parse_timing.parse_start); |
| 763 EXPECT_FALSE(updated_timings().back().paint_timing.first_paint); |
| 764 |
| 765 // 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 |
| 767 // value. |
| 768 timing.document_timing.first_layout = base::TimeDelta::FromMilliseconds(30); |
| 769 SimulateTimingUpdate(timing); |
| 770 ASSERT_EQ(2, CountUpdatedTimingReported()); |
| 771 EXPECT_NE(timing, updated_timings().back()); |
| 772 EXPECT_EQ(updated_timings().back().parse_timing, timing.parse_timing); |
| 773 EXPECT_EQ(updated_timings().back().document_timing, timing.document_timing); |
| 774 EXPECT_NE(updated_timings().back().paint_timing, timing.paint_timing); |
| 775 EXPECT_TRUE(updated_timings().back().paint_timing.first_paint); |
| 776 |
| 777 // Navigate again to see if the timing updated for a subframe message. |
| 778 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); |
| 779 |
| 780 ASSERT_EQ(1, CountCompleteTimingReported()); |
| 781 ASSERT_EQ(2, CountUpdatedTimingReported()); |
| 782 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
| 783 |
| 784 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
| 785 EXPECT_EQ(subframe_timing, updated_subframe_timings().back()); |
| 786 |
| 787 CheckNoErrorEvents(); |
| 788 } |
| 789 |
689 } // namespace page_load_metrics | 790 } // namespace page_load_metrics |
OLD | NEW |