| 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 |