Chromium Code Reviews| Index: chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
| diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
| index 1b52ea8f37126e974d13ff08f527fb609c81d5e5..0ad8fbfd6d6b25efefbc6734c778f00f470fc30b 100644 |
| --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
| +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
| @@ -30,6 +30,7 @@ |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/download_test_observer.h" |
| +#include "net/base/net_errors.h" |
| #include "net/http/failing_http_transaction_factory.h" |
| #include "net/http/http_cache.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| @@ -39,15 +40,32 @@ |
| namespace { |
| +void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| + net::HttpCache* cache( |
| + getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| + DCHECK(cache); |
| + std::unique_ptr<net::FailingHttpTransactionFactory> factory = |
| + base::MakeUnique<net::FailingHttpTransactionFactory>(cache->GetSession(), |
| + net::ERR_FAILED); |
| + // Throw away old version; since this is a browser test, there is no |
| + // need to restore the old state. |
| + cache->SetHttpNetworkTransactionFactoryForTesting(std::move(factory)); |
| +} |
| + |
| // Waits until specified timing and metadata expectations are satisfied. |
| class PageLoadMetricsWaiter |
| : public page_load_metrics::MetricsWebContentsObserver::TestingObserver { |
| public: |
| // A bitvector to express which timing fields to match on. |
| - enum ExpectedTimingFields { |
| - FIRST_PAINT = 1 << 0, |
| - FIRST_CONTENTFUL_PAINT = 1 << 1, |
| - STYLE_UPDATE_BEFORE_FCP = 1 << 2 |
| + enum class TimingField : int { |
| + FIRST_LAYOUT = 1 << 0, |
| + FIRST_PAINT = 1 << 1, |
| + FIRST_CONTENTFUL_PAINT = 1 << 2, |
| + FIRST_MEANINGFUL_PAINT = 1 << 3, |
| + STYLE_UPDATE_BEFORE_FCP = 1 << 4, |
| + DOCUMENT_WRITE_BLOCK_RELOAD = 1 << 5, |
| + LOAD_EVENT = 1 << 6 |
| }; |
| explicit PageLoadMetricsWaiter(content::WebContents* web_contents) |
| @@ -56,63 +74,119 @@ class PageLoadMetricsWaiter |
| ~PageLoadMetricsWaiter() override { DCHECK_EQ(nullptr, run_loop_.get()); } |
| // Add the given expectation to match on. |
| - void AddExpectation(ExpectedTimingFields fields) { |
| - matching_fields_ |= fields; |
| + void AddMainFrameExpectation(TimingField field) { |
| + main_frame_expected_fields_.Set(field); |
| + } |
| + void AddSubFrameExpectation(TimingField field) { |
| + child_frame_expected_fields_.Set(field); |
| } |
| - // Instructs observer to also watch for |count| |
| - // WebLoadingBehaviorDocumentWriteBlockReload events. |
| - void ExpectDocumentWriteBlockReload(int count) { |
| - match_document_write_block_reload_ = count; |
| + // Whether the given TimingField was observed in the main frame. |
| + bool DidObserveInMainFrame(TimingField field) { |
| + return observed_main_frame_fields_.IsSet(field); |
| } |
| // Waits for a TimingUpdated IPC that matches the fields set by |
| - // |AddExpectation|. All matching fields must be set in a TimingUpdated |
| - // IPC for it to end this wait. |
| + // |AddMainFrameExpectation| and |AddSubFrameExpectation|. All matching fields |
| + // must be set in a TimingUpdated IPC for it to end this wait. |
| void Wait() { |
| - if (expectations_satisfied_) |
| + if (expectations_satisfied()) |
| return; |
| run_loop_.reset(new base::RunLoop()); |
| run_loop_->Run(); |
| run_loop_.reset(nullptr); |
| - EXPECT_TRUE(expectations_satisfied_); |
| + EXPECT_TRUE(expectations_satisfied()); |
| } |
| private: |
| + // Manages a bitset of TimingFields. |
| + class TimingFieldBitSet { |
| + public: |
| + TimingFieldBitSet() {} |
| + |
| + // Returns whether this bitset has all bits unset. |
| + bool Empty() const { return bitmask_ == 0; } |
| + |
| + // Returns whether this bitset has the given bit set. |
| + bool IsSet(TimingField field) const { |
| + return (bitmask_ & static_cast<int>(field)) != 0; |
| + } |
| + |
| + // Sets the bit for the given |field|. |
| + void Set(TimingField field) { bitmask_ |= static_cast<int>(field); } |
| + |
| + // Merges bits set in |other| into this bitset. |
| + void Merge(const TimingFieldBitSet& other) { bitmask_ |= other.bitmask_; } |
| + |
| + // Clears all bits set in the |other| bitset. |
| + void ClearMatching(const TimingFieldBitSet& other) { |
| + bitmask_ &= ~other.bitmask_; |
| + } |
| + |
| + private: |
| + int bitmask_ = 0; |
| + }; |
| + |
| + static TimingFieldBitSet GetMatchedBits( |
| + const page_load_metrics::PageLoadTiming& timing, |
| + const page_load_metrics::PageLoadMetadata& metadata) { |
| + TimingFieldBitSet matched_bits; |
| + if (timing.document_timing.first_layout) |
| + matched_bits.Set(TimingField::FIRST_LAYOUT); |
| + if (timing.document_timing.load_event_start) |
| + matched_bits.Set(TimingField::LOAD_EVENT); |
| + if (timing.paint_timing.first_paint) |
| + matched_bits.Set(TimingField::FIRST_PAINT); |
| + if (timing.paint_timing.first_contentful_paint) |
| + matched_bits.Set(TimingField::FIRST_CONTENTFUL_PAINT); |
| + if (timing.paint_timing.first_meaningful_paint) |
| + matched_bits.Set(TimingField::FIRST_MEANINGFUL_PAINT); |
| + if (timing.style_sheet_timing.update_style_duration_before_fcp) |
| + matched_bits.Set(TimingField::STYLE_UPDATE_BEFORE_FCP); |
| + if (metadata.behavior_flags & |
| + blink::WebLoadingBehaviorFlag:: |
| + kWebLoadingBehaviorDocumentWriteBlockReload) |
| + matched_bits.Set(TimingField::DOCUMENT_WRITE_BLOCK_RELOAD); |
| + |
| + return matched_bits; |
| + } |
| + |
| void OnTimingUpdated( |
| + bool is_main_frame, |
| const page_load_metrics::PageLoadTiming& timing, |
| const page_load_metrics::PageLoadMetadata& metadata) override { |
| - if (match_document_write_block_reload_ > 0 && |
| - metadata.behavior_flags & |
| - blink::WebLoadingBehaviorFlag:: |
| - kWebLoadingBehaviorDocumentWriteBlockReload) { |
| - --match_document_write_block_reload_; |
| - } |
| - |
| - if (match_document_write_block_reload_ > 0) { |
| + if (expectations_satisfied()) |
| return; |
| - } |
| - if ((!(matching_fields_ & FIRST_PAINT) || |
| - timing.paint_timing.first_paint) && |
| - (!(matching_fields_ & FIRST_CONTENTFUL_PAINT) || |
| - timing.paint_timing.first_contentful_paint) && |
| - (!(matching_fields_ & STYLE_UPDATE_BEFORE_FCP) || |
| - timing.style_sheet_timing.update_style_duration_before_fcp)) { |
| - expectations_satisfied_ = true; |
| - if (run_loop_) |
| - run_loop_->Quit(); |
| + TimingFieldBitSet matched_bits = GetMatchedBits(timing, metadata); |
| + if (is_main_frame) { |
| + main_frame_expected_fields_.ClearMatching(matched_bits); |
| + observed_main_frame_fields_.Merge(matched_bits); |
| + } else { |
| + child_frame_expected_fields_.ClearMatching(matched_bits); |
| } |
| + |
| + if (expectations_satisfied() && run_loop_) |
| + run_loop_->Quit(); |
| + } |
| + |
| + bool expectations_satisfied() const { |
| + return child_frame_expected_fields_.Empty() && |
| + main_frame_expected_fields_.Empty(); |
| } |
| std::unique_ptr<base::RunLoop> run_loop_; |
| - int matching_fields_ = 0; // A bitvector composed from ExpectedTimingFields. |
| - bool expectations_satisfied_ = false; |
| - int match_document_write_block_reload_ = 0; |
| + |
| + TimingFieldBitSet child_frame_expected_fields_; |
| + TimingFieldBitSet main_frame_expected_fields_; |
| + |
| + TimingFieldBitSet observed_main_frame_fields_; |
| }; |
| +using TimingField = PageLoadMetricsWaiter::TimingField; |
| + |
| } // namespace |
| class PageLoadMetricsBrowserTest : public InProcessBrowserTest { |
| @@ -121,6 +195,10 @@ class PageLoadMetricsBrowserTest : public InProcessBrowserTest { |
| ~PageLoadMetricsBrowserTest() override {} |
| protected: |
| + // Force navigation to a new page, so the currently tracked page load runs its |
| + // OnComplete callback. You should prefer to use PageLoadMetricsWaiter, and |
| + // only use NavigateToUntrackedUrl for cases where the waiter isn't |
| + // sufficient. |
| void NavigateToUntrackedUrl() { |
| ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); |
| } |
| @@ -148,19 +226,6 @@ class PageLoadMetricsBrowserTest : public InProcessBrowserTest { |
| DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsBrowserTest); |
| }; |
| -void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) { |
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| - net::HttpCache* cache( |
| - getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| - DCHECK(cache); |
| - std::unique_ptr<net::FailingHttpTransactionFactory> factory( |
| - new net::FailingHttpTransactionFactory(cache->GetSession(), |
| - net::ERR_FAILED)); |
| - // Throw away old version; since this is a browser test, there is no |
| - // need to restore the old state. |
| - cache->SetHttpNetworkTransactionFactoryForTesting(std::move(factory)); |
| -} |
| - |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoNavigation) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| EXPECT_TRUE(NoPageLoadMetricsRecorded()); |
| @@ -169,18 +234,25 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoNavigation) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NewPage) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_PAINT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| - NavigateToUntrackedUrl(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 1); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramParseDuration, 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramParseBlockedOnScriptLoad, 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramParseBlockedOnScriptExecution, 1); |
| + |
| + // Force navigation to another page, which should force logging of histograms |
| + // persisted at the end of the page load lifetime. |
| + NavigateToUntrackedUrl(); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramPageTimingForegroundDuration, 1); |
| @@ -190,11 +262,39 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NewPage) { |
| EXPECT_FALSE(NoPageLoadMetricsRecorded()); |
| } |
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoPaintForEmptyDocument) { |
| + ASSERT_TRUE(embedded_test_server()->Start()); |
| + |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| + ui_test_utils::NavigateToURL(browser(), |
| + embedded_test_server()->GetURL("/empty.html")); |
| + waiter->Wait(); |
| + EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingField::FIRST_PAINT)); |
| + |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 0); |
| +} |
| + |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, SameDocumentNavigation) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| + waiter->Wait(); |
| + |
|
jkarlin
2017/05/11 14:04:06
EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingF
Bryan McQuade
2017/05/11 14:07:03
For better or worse, title1.html does paint, so we
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| + |
| + // Perform a same-document navigation. No additional metrics should be logged. |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL("/title1.html#hash")); |
| NavigateToUntrackedUrl(); |
| @@ -207,11 +307,23 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, SameDocumentNavigation) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, SameUrlNavigation) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| + waiter->Wait(); |
| + |
|
jkarlin
2017/05/11 14:04:05
EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingF
Bryan McQuade
2017/05/11 14:07:03
Same
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1); |
| + |
| + waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_LAYOUT); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| - NavigateToUntrackedUrl(); |
| + waiter->Wait(); |
|
jkarlin
2017/05/11 14:04:06
EXPECT_FALSE(waiter->DidObserveInMainFrame(TimingF
Bryan McQuade
2017/05/11 14:07:03
Same
|
| // We expect one histogram sample for each navigation to title1.html. |
| histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 2); |
| @@ -296,14 +408,13 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, IgnoreDownloads) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, PreloadDocumentWrite) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_external_script.html")); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 1); |
| @@ -312,11 +423,15 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, PreloadDocumentWrite) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoPreloadDocumentWrite) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_no_script.html")); |
| - NavigateToUntrackedUrl(); |
| + waiter->Wait(); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0); |
| } |
| @@ -324,14 +439,15 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoPreloadDocumentWrite) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoDocumentWrite) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0); |
| histogram_tester_.ExpectTotalCount( |
| @@ -342,14 +458,13 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoDocumentWrite) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteBlock) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_script_block.html")); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1); |
| @@ -359,30 +474,37 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteBlock) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteReload) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| - std::unique_ptr<PageLoadMetricsWaiter> reload_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - reload_waiter->ExpectDocumentWriteBlockReload(2); |
| - |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_script_block.html")); |
| + waiter->Wait(); |
| + |
| + histogram_tester_.ExpectTotalCount( |
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1); |
| // Reload should not log the histogram as the script is not blocked. |
| + auto reload_waiter = CreatePageLoadMetricsWaiter(); |
| + reload_waiter->AddMainFrameExpectation( |
| + TimingField::DOCUMENT_WRITE_BLOCK_RELOAD); |
| + reload_waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_script_block.html")); |
| + reload_waiter->Wait(); |
| + |
| + histogram_tester_.ExpectTotalCount( |
| + internal::kHistogramDocWriteBlockReloadCount, 1); |
| + reload_waiter = CreatePageLoadMetricsWaiter(); |
| + reload_waiter->AddMainFrameExpectation( |
| + TimingField::DOCUMENT_WRITE_BLOCK_RELOAD); |
| + reload_waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_script_block.html")); |
| - |
| - histogram_tester_.ExpectTotalCount( |
| - internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1); |
| - |
| - fcp_waiter->Wait(); |
| reload_waiter->Wait(); |
| histogram_tester_.ExpectTotalCount( |
| @@ -396,11 +518,15 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteReload) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteAsync) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| - "/page_load_metrics/document_write_script_async.html")); |
| - NavigateToUntrackedUrl(); |
| + "/page_load_metrics/document_write_async_script.html")); |
| + waiter->Wait(); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0); |
| @@ -409,11 +535,15 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteAsync) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteSameDomain) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_external_script.html")); |
| - NavigateToUntrackedUrl(); |
| + waiter->Wait(); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0); |
| @@ -422,11 +552,15 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, DocumentWriteSameDomain) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoDocumentWriteScript) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/document_write_no_script.html")); |
| - NavigateToUntrackedUrl(); |
| + waiter->Wait(); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 1); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0); |
| @@ -441,9 +575,8 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoDocumentWriteScript) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, MAYBE_BadXhtml) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> timing_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - timing_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_PAINT); |
| // When an XHTML page contains invalid XML, it causes a paint of the error |
| // message without a layout. Page load metrics currently treats this as an |
| @@ -454,7 +587,7 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, MAYBE_BadXhtml) { |
| browser(), |
| embedded_test_server()->GetURL("/page_load_metrics/badxml.xhtml")); |
| - timing_waiter->Wait(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 0); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0); |
| @@ -488,11 +621,12 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, AbortNewNavigation) { |
| GURL url2(embedded_test_server()->GetURL("/title2.html")); |
| chrome::NavigateParams params2(browser(), url2, |
| ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); |
| - content::TestNavigationManager manager2( |
| - browser()->tab_strip_model()->GetActiveWebContents(), url2); |
| + |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| chrome::Navigate(¶ms2); |
| + waiter->Wait(); |
| - manager2.WaitForNavigationFinished(); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramAbortNewNavigationBeforeCommit, 1); |
| } |
| @@ -509,11 +643,12 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, AbortReload) { |
| EXPECT_TRUE(manager.WaitForRequestStart()); |
| chrome::NavigateParams params2(browser(), url, ui::PAGE_TRANSITION_RELOAD); |
| - content::TestNavigationManager manager2( |
| - browser()->tab_strip_model()->GetActiveWebContents(), url); |
| + |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| chrome::Navigate(¶ms2); |
| + waiter->Wait(); |
| - manager2.WaitForNavigationFinished(); |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramAbortReloadBeforeCommit, 1); |
| } |
| @@ -565,15 +700,14 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, AbortMultiple) { |
| GURL url3(embedded_test_server()->GetURL("/title3.html")); |
| chrome::NavigateParams params3(browser(), url3, ui::PAGE_TRANSITION_TYPED); |
| - content::TestNavigationManager manager3( |
| - browser()->tab_strip_model()->GetActiveWebContents(), url3); |
| + |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| chrome::Navigate(¶ms3); |
| + waiter->Wait(); |
| - EXPECT_TRUE(manager3.WaitForRequestStart()); |
| manager2.WaitForNavigationFinished(); |
| - manager3.WaitForNavigationFinished(); |
| - |
| histogram_tester_.ExpectTotalCount( |
| internal::kHistogramAbortNewNavigationBeforeCommit, 2); |
| } |
| @@ -594,11 +728,14 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| EXPECT_TRUE(manager.WaitForRequestStart()); |
| { |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| content::TestNavigationManager reload_manager( |
| browser()->tab_strip_model()->GetActiveWebContents(), first_url); |
| EXPECT_TRUE(content::ExecuteScript( |
| browser()->tab_strip_model()->GetActiveWebContents(), |
| "window.location.reload();")); |
| + waiter->Wait(); |
| } |
| manager.WaitForNavigationFinished(); |
| @@ -612,22 +749,12 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| FirstMeaningfulPaintRecorded) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_MEANINGFUL_PAINT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| + waiter->Wait(); |
| - // Wait until the renderer finishes observing layouts. |
| - const int kNetworkIdleTime = 3000; |
| - const int kMargin = 500; |
| - const std::string javascript = base::StringPrintf( |
| - "setTimeout(() => window.domAutomationController.send(true), %d)", |
| - kNetworkIdleTime + kMargin); |
| - bool result; |
| - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
| - browser()->tab_strip_model()->GetActiveWebContents(), |
| - javascript, &result)); |
| - EXPECT_TRUE(result); |
| - |
| - NavigateToUntrackedUrl(); |
| histogram_tester_.ExpectUniqueSample( |
| internal::kHistogramFirstMeaningfulPaintStatus, |
| internal::FIRST_MEANINGFUL_PAINT_RECORDED, 1); |
| @@ -641,18 +768,19 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| FirstMeaningfulPaintNotRecorded) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/page_with_active_connections.html")); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| // Navigate away before a FMP is reported. |
| NavigateToUntrackedUrl(); |
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| + 1); |
| histogram_tester_.ExpectUniqueSample( |
| internal::kHistogramFirstMeaningfulPaintStatus, |
| internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, 1); |
| @@ -666,14 +794,13 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| NoStatePrefetchObserverCacheable) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/title1.html")); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount( |
| "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 0); |
| @@ -685,14 +812,13 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| NoStatePrefetchObserverNoStore) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::FIRST_CONTENTFUL_PAINT); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::FIRST_CONTENTFUL_PAINT); |
| ui_test_utils::NavigateToURL(browser(), |
| embedded_test_server()->GetURL("/nostore.html")); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount( |
| "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 1); |
| @@ -703,9 +829,8 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, CSSTiming) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| - std::unique_ptr<PageLoadMetricsWaiter> fcp_waiter = |
| - CreatePageLoadMetricsWaiter(); |
| - fcp_waiter->AddExpectation(PageLoadMetricsWaiter::STYLE_UPDATE_BEFORE_FCP); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::STYLE_UPDATE_BEFORE_FCP); |
| // Careful: Blink code clamps timestamps to 5us, so any CSS parsing we do here |
| // must take >> 5us, otherwise we'll log 0 for the value and it will remain |
| @@ -713,8 +838,7 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, CSSTiming) { |
| ui_test_utils::NavigateToURL( |
| browser(), |
| embedded_test_server()->GetURL("/page_load_metrics/page_with_css.html")); |
| - NavigateToUntrackedUrl(); |
| - fcp_waiter->Wait(); |
| + waiter->Wait(); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint, |
| 1); |
| @@ -729,8 +853,14 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, CSSTiming) { |
| IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, PayloadSize) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| + auto waiter = CreatePageLoadMetricsWaiter(); |
| + waiter->AddMainFrameExpectation(TimingField::LOAD_EVENT); |
| ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL( |
| "/page_load_metrics/large.html")); |
| + waiter->Wait(); |
| + |
| + // Payload histograms are only logged when a page load terminates, so force |
| + // navigation to another page. |
| NavigateToUntrackedUrl(); |
| histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1); |