| 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 "base/command_line.h" |
| 6 #include "base/feature_list.h" |
| 5 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
| 6 #include "base/macros.h" | 8 #include "base/macros.h" |
| 7 #include "base/test/histogram_tester.h" | 9 #include "base/test/histogram_tester.h" |
| 8 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
| 9 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 10 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" | 12 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" |
| 11 #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_ob
server.h" | 13 #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_ob
server.h" |
| 12 #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_obse
rver.h" | 14 #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_obse
rver.h" |
| 13 #include "chrome/browser/page_load_metrics/observers/document_write_page_load_me
trics_observer.h" | 15 #include "chrome/browser/page_load_metrics/observers/document_write_page_load_me
trics_observer.h" |
| 14 #include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load
_metrics_observer.h" | 16 #include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load
_metrics_observer.h" |
| 15 #include "chrome/browser/page_load_metrics/page_load_tracker.h" | 17 #include "chrome/browser/page_load_metrics/page_load_tracker.h" |
| 16 #include "chrome/browser/prerender/prerender_histograms.h" | 18 #include "chrome/browser/prerender/prerender_histograms.h" |
| 17 #include "chrome/browser/prerender/prerender_origin.h" | 19 #include "chrome/browser/prerender/prerender_origin.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ui/browser.h" | 21 #include "chrome/browser/ui/browser.h" |
| 20 #include "chrome/browser/ui/browser_navigator_params.h" | 22 #include "chrome/browser/ui/browser_navigator_params.h" |
| 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 22 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h" | 24 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h" |
| 23 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
| 24 #include "chrome/common/url_constants.h" | 26 #include "chrome/common/url_constants.h" |
| 25 #include "chrome/test/base/in_process_browser_test.h" | 27 #include "chrome/test/base/in_process_browser_test.h" |
| 26 #include "chrome/test/base/ui_test_utils.h" | 28 #include "chrome/test/base/ui_test_utils.h" |
| 27 #include "components/prefs/pref_service.h" | 29 #include "components/prefs/pref_service.h" |
| 28 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/render_process_host.h" | 31 #include "content/public/browser/render_process_host.h" |
| 30 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
| 33 #include "content/public/common/content_features.h" |
| 34 #include "content/public/common/content_switches.h" |
| 31 #include "content/public/test/browser_test_utils.h" | 35 #include "content/public/test/browser_test_utils.h" |
| 32 #include "content/public/test/download_test_observer.h" | 36 #include "content/public/test/download_test_observer.h" |
| 33 #include "net/base/net_errors.h" | 37 #include "net/base/net_errors.h" |
| 38 #include "net/dns/mock_host_resolver.h" |
| 34 #include "net/http/failing_http_transaction_factory.h" | 39 #include "net/http/failing_http_transaction_factory.h" |
| 35 #include "net/http/http_cache.h" | 40 #include "net/http/http_cache.h" |
| 36 #include "net/test/embedded_test_server/embedded_test_server.h" | 41 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 37 #include "net/test/url_request/url_request_failed_job.h" | 42 #include "net/test/url_request/url_request_failed_job.h" |
| 38 #include "net/url_request/url_request_context.h" | 43 #include "net/url_request/url_request_context.h" |
| 39 #include "net/url_request/url_request_context_getter.h" | 44 #include "net/url_request/url_request_context_getter.h" |
| 40 | 45 |
| 41 namespace { | 46 namespace { |
| 42 | 47 |
| 43 void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) { | 48 void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 } | 183 } |
| 179 | 184 |
| 180 std::unique_ptr<base::RunLoop> run_loop_; | 185 std::unique_ptr<base::RunLoop> run_loop_; |
| 181 | 186 |
| 182 TimingFieldBitSet child_frame_expected_fields_; | 187 TimingFieldBitSet child_frame_expected_fields_; |
| 183 TimingFieldBitSet main_frame_expected_fields_; | 188 TimingFieldBitSet main_frame_expected_fields_; |
| 184 | 189 |
| 185 TimingFieldBitSet observed_main_frame_fields_; | 190 TimingFieldBitSet observed_main_frame_fields_; |
| 186 }; | 191 }; |
| 187 | 192 |
| 193 // Due to crbug/705315, paints in subframes are associated with the main frame, |
| 194 // unless the subframe is cross-origin and Chrome is running with out of process |
| 195 // cross-origin subframes. As a result, some tests wait for different behavior |
| 196 // to be observed depending on which mode we are in. TODO(crbug/705315): remove |
| 197 // this method once the bug is addressed. |
| 198 static bool AreCrossOriginSubFramesOutOfProcess() { |
| 199 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 200 switches::kSitePerProcess) || |
| 201 base::FeatureList::IsEnabled(features::kTopDocumentIsolation); |
| 202 } |
| 203 |
| 188 using TimingField = PageLoadMetricsWaiter::TimingField; | 204 using TimingField = PageLoadMetricsWaiter::TimingField; |
| 189 | 205 |
| 190 } // namespace | 206 } // namespace |
| 191 | 207 |
| 192 class PageLoadMetricsBrowserTest : public InProcessBrowserTest { | 208 class PageLoadMetricsBrowserTest : public InProcessBrowserTest { |
| 193 public: | 209 public: |
| 194 PageLoadMetricsBrowserTest() {} | 210 PageLoadMetricsBrowserTest() {} |
| 195 ~PageLoadMetricsBrowserTest() override {} | 211 ~PageLoadMetricsBrowserTest() override {} |
| 196 | 212 |
| 197 protected: | 213 protected: |
| 198 // Force navigation to a new page, so the currently tracked page load runs its | 214 // Force navigation to a new page, so the currently tracked page load runs its |
| 199 // OnComplete callback. You should prefer to use PageLoadMetricsWaiter, and | 215 // OnComplete callback. You should prefer to use PageLoadMetricsWaiter, and |
| 200 // only use NavigateToUntrackedUrl for cases where the waiter isn't | 216 // only use NavigateToUntrackedUrl for cases where the waiter isn't |
| 201 // sufficient. | 217 // sufficient. |
| 202 void NavigateToUntrackedUrl() { | 218 void NavigateToUntrackedUrl() { |
| 203 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); | 219 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); |
| 204 } | 220 } |
| 205 | 221 |
| 222 // TODO(crbug/705315): remove this method once the bug is addressed. |
| 223 void SetUpOnMainThread() override { |
| 224 InProcessBrowserTest::SetUpOnMainThread(); |
| 225 host_resolver()->AddRule("a.com", "127.0.0.1"); |
| 226 host_resolver()->AddRule("b.com", "127.0.0.1"); |
| 227 host_resolver()->AddRule("c.com", "127.0.0.1"); |
| 228 content::SetupCrossSiteRedirector(embedded_test_server()); |
| 229 } |
| 230 |
| 206 bool NoPageLoadMetricsRecorded() { | 231 bool NoPageLoadMetricsRecorded() { |
| 207 // Determine whether any 'public' page load metrics are recorded. We exclude | 232 // Determine whether any 'public' page load metrics are recorded. We exclude |
| 208 // 'internal' metrics as these may be recorded for debugging purposes. | 233 // 'internal' metrics as these may be recorded for debugging purposes. |
| 209 size_t total_pageload_histograms = | 234 size_t total_pageload_histograms = |
| 210 histogram_tester_.GetTotalCountsForPrefix("PageLoad.").size(); | 235 histogram_tester_.GetTotalCountsForPrefix("PageLoad.").size(); |
| 211 size_t total_internal_histograms = | 236 size_t total_internal_histograms = |
| 212 histogram_tester_.GetTotalCountsForPrefix("PageLoad.Internal.").size(); | 237 histogram_tester_.GetTotalCountsForPrefix("PageLoad.Internal.").size(); |
| 213 DCHECK_GE(total_pageload_histograms, total_internal_histograms); | 238 DCHECK_GE(total_pageload_histograms, total_internal_histograms); |
| 214 return total_pageload_histograms - total_internal_histograms == 0; | 239 return total_pageload_histograms - total_internal_histograms == 0; |
| 215 } | 240 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 waiter->Wait(); | 298 waiter->Wait(); |
| 274 EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingField::FIRST_PAINT)); | 299 EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingField::FIRST_PAINT)); |
| 275 | 300 |
| 276 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); | 301 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| 277 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); | 302 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| 278 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0); | 303 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0); |
| 279 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, | 304 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| 280 0); | 305 0); |
| 281 } | 306 } |
| 282 | 307 |
| 308 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| 309 NoPaintForEmptyDocumentInChildFrame) { |
| 310 ASSERT_TRUE(embedded_test_server()->Start()); |
| 311 |
| 312 // TODO(crbug/705315): remove the a.com domain once the bug is addressed. |
| 313 GURL a_url(embedded_test_server()->GetURL( |
| 314 "a.com", "/page_load_metrics/empty_iframe.html")); |
| 315 |
| 316 auto waiter = CreatePageLoadMetricsWaiter(); |
| 317 waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| 318 waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| 319 waiter->AddSubFrameExpectation(TimingField::FIRST_LAYOUT); |
| 320 waiter->AddSubFrameExpectation(TimingField::LOAD_EVENT); |
| 321 ui_test_utils::NavigateToURL(browser(), a_url); |
| 322 waiter->Wait(); |
| 323 EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingField::FIRST_PAINT)); |
| 324 |
| 325 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| 326 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| 327 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0); |
| 328 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| 329 0); |
| 330 } |
| 331 |
| 332 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, PaintInChildFrame) { |
| 333 ASSERT_TRUE(embedded_test_server()->Start()); |
| 334 |
| 335 // TODO(crbug/705315): remove the a.com domain once the bug is addressed. |
| 336 GURL a_url(embedded_test_server()->GetURL("a.com", |
| 337 "/page_load_metrics/iframe.html")); |
| 338 auto waiter = CreatePageLoadMetricsWaiter(); |
| 339 waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| 340 waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| 341 // TODO(crbug/705315): Once the bug is fixed, remove the else case and make |
| 342 // the if case the default behavior. |
| 343 if (AreCrossOriginSubFramesOutOfProcess()) { |
| 344 waiter->AddSubFrameExpectation(TimingField::FIRST_PAINT); |
| 345 waiter->AddSubFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| 346 } else { |
| 347 waiter->AddMainFrameExpectation(TimingField::FIRST_PAINT); |
| 348 waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| 349 } |
| 350 ui_test_utils::NavigateToURL(browser(), a_url); |
| 351 waiter->Wait(); |
| 352 |
| 353 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| 354 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| 355 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 1); |
| 356 } |
| 357 |
| 358 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, PaintInMultipleChildFrames) { |
| 359 ASSERT_TRUE(embedded_test_server()->Start()); |
| 360 |
| 361 // TODO(crbug/705315): remove the a.com domain once the bug is addressed. |
| 362 GURL a_url(embedded_test_server()->GetURL("a.com", |
| 363 "/page_load_metrics/iframes.html")); |
| 364 |
| 365 auto waiter = CreatePageLoadMetricsWaiter(); |
| 366 waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| 367 waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| 368 // TODO(crbug/705315): Once the bug is fixed, remove the else case and make |
| 369 // the if case the default behavior. |
| 370 if (AreCrossOriginSubFramesOutOfProcess()) { |
| 371 waiter->AddSubFrameExpectation(TimingField::FIRST_PAINT); |
| 372 waiter->AddSubFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| 373 } else { |
| 374 waiter->AddMainFrameExpectation(TimingField::FIRST_PAINT); |
| 375 waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| 376 } |
| 377 ui_test_utils::NavigateToURL(browser(), a_url); |
| 378 waiter->Wait(); |
| 379 |
| 380 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| 381 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| 382 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 1); |
| 383 } |
| 384 |
| 385 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, PaintInMainAndChildFrame) { |
| 386 ASSERT_TRUE(embedded_test_server()->Start()); |
| 387 |
| 388 // TODO(crbug/705315): remove the a.com domain once the bug is addressed. |
| 389 GURL a_url(embedded_test_server()->GetURL( |
| 390 "a.com", "/page_load_metrics/main_frame_with_iframe.html")); |
| 391 |
| 392 auto waiter = CreatePageLoadMetricsWaiter(); |
| 393 waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| 394 waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| 395 waiter->AddMainFrameExpectation(TimingField::FIRST_PAINT); |
| 396 waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| 397 // TODO(crbug/705315): Once the bug is fixed, make the if case the default |
| 398 // behavior. |
| 399 if (AreCrossOriginSubFramesOutOfProcess()) { |
| 400 waiter->AddSubFrameExpectation(TimingField::FIRST_PAINT); |
| 401 waiter->AddSubFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| 402 } |
| 403 ui_test_utils::NavigateToURL(browser(), a_url); |
| 404 waiter->Wait(); |
| 405 |
| 406 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| 407 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| 408 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 1); |
| 409 } |
| 410 |
| 283 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, SameDocumentNavigation) { | 411 IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, SameDocumentNavigation) { |
| 284 ASSERT_TRUE(embedded_test_server()->Start()); | 412 ASSERT_TRUE(embedded_test_server()->Start()); |
| 285 | 413 |
| 286 auto waiter = CreatePageLoadMetricsWaiter(); | 414 auto waiter = CreatePageLoadMetricsWaiter(); |
| 287 waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); | 415 waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| 288 waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); | 416 waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| 289 ui_test_utils::NavigateToURL(browser(), | 417 ui_test_utils::NavigateToURL(browser(), |
| 290 embedded_test_server()->GetURL("/title1.html")); | 418 embedded_test_server()->GetURL("/title1.html")); |
| 291 waiter->Wait(); | 419 waiter->Wait(); |
| 292 | 420 |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 // Payload histograms are only logged when a page load terminates, so force | 990 // Payload histograms are only logged when a page load terminates, so force |
| 863 // navigation to another page. | 991 // navigation to another page. |
| 864 NavigateToUntrackedUrl(); | 992 NavigateToUntrackedUrl(); |
| 865 | 993 |
| 866 histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1); | 994 histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1); |
| 867 | 995 |
| 868 // Verify that there is a single sample recorded in the 10kB bucket (the size | 996 // Verify that there is a single sample recorded in the 10kB bucket (the size |
| 869 // of the main HTML response). | 997 // of the main HTML response). |
| 870 histogram_tester_.ExpectBucketCount(internal::kHistogramTotalBytes, 10, 1); | 998 histogram_tester_.ExpectBucketCount(internal::kHistogramTotalBytes, 10, 1); |
| 871 } | 999 } |
| OLD | NEW |