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