| Index: chrome/browser/page_load_metrics/page_load_metrics_mojofication_browsertest.cc
|
| diff --git a/chrome/browser/page_load_metrics/page_load_metrics_mojofication_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_mojofication_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..aef526fea94b17ac0de2f1ca3cf17c9b6c4a64a6
|
| --- /dev/null
|
| +++ b/chrome/browser/page_load_metrics/page_load_metrics_mojofication_browsertest.cc
|
| @@ -0,0 +1,923 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/files/scoped_temp_dir.h"
|
| +#include "base/macros.h"
|
| +#include "base/test/histogram_tester.h"
|
| +#include "base/test/scoped_feature_list.h"
|
| +#include "base/time/time.h"
|
| +#include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
|
| +#include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h"
|
| +#include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h"
|
| +#include "chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h"
|
| +#include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load_metrics_observer.h"
|
| +#include "chrome/browser/page_load_metrics/page_load_tracker.h"
|
| +#include "chrome/browser/prerender/prerender_histograms.h"
|
| +#include "chrome/browser/prerender/prerender_origin.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/browser_navigator_params.h"
|
| +#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/common/chrome_features.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "chrome/common/url_constants.h"
|
| +#include "chrome/test/base/in_process_browser_test.h"
|
| +#include "chrome/test/base/ui_test_utils.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#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 "content/public/test/web_contents_binding_set_test_binder.h"
|
| +#include "mojo/public/cpp/bindings/associated_binding.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"
|
| +#include "net/test/url_request/url_request_failed_job.h"
|
| +#include "net/url_request/url_request_context.h"
|
| +#include "net/url_request/url_request_context_getter.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +
|
| +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(
|
| + 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));
|
| +}
|
| +
|
| +// Wait until we dispatch PageLoadTiming through UpdateTiming.
|
| +// matching a PageLoadTiming. See WaitForTimingUpdated for details.
|
| +class PageLoadTimingObserver {
|
| + 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
|
| + };
|
| +
|
| + PageLoadTimingObserver() {
|
| + // Roundtrip to the IO thread, to ensure that the filter is properly
|
| + // installed.
|
| + content::BrowserThread::PostTaskAndReply(
|
| + content::BrowserThread::IO, FROM_HERE, base::Bind(&base::DoNothing),
|
| + base::Bind(&PageLoadTimingObserver::Quit, base::Unretained(this)));
|
| + run_loop_.reset(new base::RunLoop());
|
| + run_loop_->Run();
|
| + run_loop_.reset(nullptr);
|
| + }
|
| +
|
| + ~PageLoadTimingObserver() {}
|
| +
|
| + // Add the given timing fields to the set of fields to match on.
|
| + void AddMatchingFields(ExpectedTimingFields fields) {
|
| + matching_fields_ |= fields;
|
| + }
|
| +
|
| + // Instructs observer to also watch for |count|
|
| + // WebLoadingBehaviorDocumentWriteBlockReload events.
|
| + void MatchDocumentWriteBlockReload(int count) {
|
| + match_document_write_block_reload_ = count;
|
| + }
|
| +
|
| + // Waits for a PageLoadTiming that matches the fields set by
|
| + // Waits for a TimingUpdated IPC that matches the fields set by
|
| + // UpdateTiming to end this wait.
|
| + void WaitForTimingUpdated() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + if (matched_timing_update_)
|
| + return;
|
| +
|
| + run_loop_.reset(new base::RunLoop());
|
| + run_loop_->Run();
|
| + run_loop_.reset(nullptr);
|
| + }
|
| +
|
| + void UpdateTiming(const page_load_metrics::PageLoadTiming& timing,
|
| + const page_load_metrics::PageLoadMetadata& metadata) {
|
| + 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) {
|
| + 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)) {
|
| + // Ensure that any other handlers of this message, for example the real
|
| + // PageLoadMetric observers, get a chance to handle this message before
|
| + // this waiter unblocks.
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&PageLoadTimingObserver::BounceTimingUpdate,
|
| + base::Unretained(this)));
|
| + }
|
| + }
|
| +
|
| + private:
|
| + void BounceTimingUpdate() {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&PageLoadTimingObserver::SetTimingUpdatedAndQuit,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void Quit() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + if (run_loop_)
|
| + run_loop_->Quit();
|
| + }
|
| +
|
| + void SetTimingUpdatedAndQuit() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + matched_timing_update_ = true;
|
| + Quit();
|
| + }
|
| +
|
| + std::unique_ptr<base::RunLoop> run_loop_;
|
| + int matching_fields_ = 0; // A bitvector composed from ExpectedTimingFields.
|
| + bool matched_timing_update_ = false;
|
| + int match_document_write_block_reload_ = 0;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +namespace page_load_metrics {
|
| +
|
| +class FakePageLoadMetrics : public mojom::PageLoadMetrics {
|
| + public:
|
| + explicit FakePageLoadMetrics(content::RenderFrameHost* render_frame_host) {
|
| + metrics_observer_ = content::WebContentsUserData<
|
| + page_load_metrics::MetricsWebContentsObserver>::
|
| + FromWebContents(
|
| + content::WebContents::FromRenderFrameHost(render_frame_host));
|
| + metrics_observer_->page_load_metrics_binding_for_testing()
|
| + .SetCurrentTargetFrameForTesting(render_frame_host);
|
| + }
|
| +
|
| + ~FakePageLoadMetrics() override {}
|
| +
|
| + void AddObserver(PageLoadTimingObserver* observer) {
|
| + observers_.push_back(base::WrapUnique(observer));
|
| + }
|
| +
|
| + private:
|
| + void UpdateTiming(const PageLoadTiming& timing,
|
| + const PageLoadMetadata& metadata) override {
|
| + metrics_observer_->UpdateTiming(timing, metadata);
|
| + for (auto& observer : observers_) {
|
| + observer->UpdateTiming(timing, metadata);
|
| + }
|
| + }
|
| +
|
| + MetricsWebContentsObserver* metrics_observer_;
|
| + std::vector<std::unique_ptr<PageLoadTimingObserver>> observers_;
|
| +};
|
| +
|
| +} // namespace page_load_metrics
|
| +
|
| +namespace {
|
| +
|
| +class FakePageLoadMetricsBinder
|
| + : public content::WebContentsBindingSetTestBinder<
|
| + page_load_metrics::mojom::PageLoadMetrics> {
|
| + public:
|
| + FakePageLoadMetricsBinder(
|
| + page_load_metrics::mojom::PageLoadMetrics* page_load_metrics)
|
| + : page_load_metrics_(page_load_metrics) {}
|
| + ~FakePageLoadMetricsBinder() override {}
|
| +
|
| + void BindRequest(content::RenderFrameHost* frame_host,
|
| + page_load_metrics::mojom::PageLoadMetricsAssociatedRequest
|
| + request) override {
|
| + bindings_.AddBinding(page_load_metrics_, std::move(request), frame_host);
|
| + }
|
| +
|
| + private:
|
| + page_load_metrics::mojom::PageLoadMetrics* page_load_metrics_;
|
| + mojo::AssociatedBindingSet<page_load_metrics::mojom::PageLoadMetrics,
|
| + content::RenderFrameHost*>
|
| + bindings_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(FakePageLoadMetricsBinder);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class PageLoadMetricsMojoficationBrowserTest : public InProcessBrowserTest {
|
| + public:
|
| + PageLoadMetricsMojoficationBrowserTest() {}
|
| + ~PageLoadMetricsMojoficationBrowserTest() override {}
|
| +
|
| + void SetUpCommandLine(base::CommandLine* command_line) override {
|
| + // We need to set the feature state before the render process is created,
|
| + // in order for it to inherit the feature state from the browser process.
|
| + // SetUp() runs too early, and SetUpOnMainThread() runs too late.
|
| + scoped_feature_list_.InitAndEnableFeature(
|
| + features::kPageLoadMetricsMojofication);
|
| + }
|
| +
|
| + protected:
|
| + void NavigateToUntrackedUrl() {
|
| + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
|
| + }
|
| +
|
| + bool NoPageLoadMetricsRecorded() {
|
| + // Determine whether any 'public' page load metrics are recorded. We exclude
|
| + // 'internal' metrics as these may be recorded for debugging purposes.
|
| + size_t total_pageload_histograms =
|
| + histogram_tester_.GetTotalCountsForPrefix("PageLoad.").size();
|
| + size_t total_internal_histograms =
|
| + histogram_tester_.GetTotalCountsForPrefix("PageLoad.Internal.").size();
|
| + DCHECK_GE(total_pageload_histograms, total_internal_histograms);
|
| + return total_pageload_histograms - total_internal_histograms == 0;
|
| + }
|
| +
|
| + PageLoadTimingObserver* CreatePageLoadTimingObserver() {
|
| + if (!fake_page_load_metrics_) {
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + fake_page_load_metrics_.reset(new page_load_metrics::FakePageLoadMetrics(
|
| + web_contents->GetMainFrame()));
|
| + content::WebContentsBindingSet::GetForWebContents<
|
| + page_load_metrics::mojom::PageLoadMetrics>(web_contents)
|
| + ->SetBinderForTesting(base::MakeUnique<FakePageLoadMetricsBinder>(
|
| + fake_page_load_metrics_.get()));
|
| + }
|
| + PageLoadTimingObserver* observer = new PageLoadTimingObserver();
|
| + fake_page_load_metrics_->AddObserver(observer);
|
| + return observer;
|
| + }
|
| +
|
| + base::test::ScopedFeatureList scoped_feature_list_;
|
| + std::unique_ptr<page_load_metrics::FakePageLoadMetrics>
|
| + fake_page_load_metrics_;
|
| + base::HistogramTester histogram_tester_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsMojoficationBrowserTest);
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, NoNavigation) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, NewPage) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramParseDuration, 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramParseBlockedOnScriptLoad, 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramParseBlockedOnScriptExecution, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramPageTimingForegroundDuration, 1);
|
| +
|
| + // Verify that NoPageLoadMetricsRecorded returns false when PageLoad metrics
|
| + // have been recorded.
|
| + EXPECT_FALSE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + SameDocumentNavigation) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL("/title1.html#hash"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + SameUrlNavigation) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + // We expect one histogram sample for each navigation to title1.html.
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 2);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 2);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 2);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NonHtmlMainResource) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/circle.svg"));
|
| + NavigateToUntrackedUrl();
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NonHttpOrHttpsUrl) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL));
|
| + NavigateToUntrackedUrl();
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, HttpErrorPage) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL("/page_load_metrics/404.html"));
|
| + NavigateToUntrackedUrl();
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + ChromeErrorPage) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + // Configure the network stack to fail all attempted loads with a network
|
| + // error, which will cause Chrome to display an error page.
|
| + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
|
| + browser()->profile()->GetRequestContext();
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&FailAllNetworkTransactions,
|
| + base::RetainedRef(url_request_context_getter)));
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| + NavigateToUntrackedUrl();
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, Ignore204Pages) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/page204.html"));
|
| + NavigateToUntrackedUrl();
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + IgnoreDownloads) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + base::ScopedTempDir downloads_directory;
|
| + ASSERT_TRUE(downloads_directory.CreateUniqueTempDir());
|
| + browser()->profile()->GetPrefs()->SetFilePath(
|
| + prefs::kDownloadDefaultDirectory, downloads_directory.GetPath());
|
| + content::DownloadTestObserverTerminal downloads_observer(
|
| + content::BrowserContext::GetDownloadManager(browser()->profile()),
|
| + 1, // == wait_count (only waiting for "download-test3.gif").
|
| + content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL("/download-test3.gif"));
|
| + downloads_observer.WaitForFinished();
|
| +
|
| + NavigateToUntrackedUrl();
|
| + EXPECT_TRUE(NoPageLoadMetricsRecorded());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + PreloadDocumentWrite) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_external_script.html"));
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NoPreloadDocumentWrite) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_no_script.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NoDocumentWrite) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0);
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + DocumentWriteBlock) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_script_block.html"));
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + DocumentWriteReload) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| + PageLoadTimingObserver* reload_observer = CreatePageLoadTimingObserver();
|
| + reload_observer->MatchDocumentWriteBlockReload(2);
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_script_block.html"));
|
| +
|
| + // Reload should not log the histogram as the script is not blocked.
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_script_block.html"));
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_script_block.html"));
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
|
| +
|
| + fcp_observer->WaitForTimingUpdated();
|
| + reload_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockReloadCount, 2);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + DocumentWriteAsync) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_script_async.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + DocumentWriteSameDomain) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_external_script.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NoDocumentWriteScript) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/document_write_no_script.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, BadXhtml) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* timing_observer = CreatePageLoadTimingObserver();
|
| + timing_observer->AddMatchingFields(PageLoadTimingObserver::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
|
| + // error. Eventually, we'll fix this by special casing the handling of
|
| + // documents with non-well-formed XML on the blink side. See crbug.com/627607
|
| + // for more.
|
| + ui_test_utils::NavigateToURL(
|
| + browser(),
|
| + embedded_test_server()->GetURL("/page_load_metrics/badxml.xhtml"));
|
| +
|
| + timing_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 0);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0);
|
| + histogram_tester_.ExpectTotalCount(page_load_metrics::internal::kErrorEvents,
|
| + 1);
|
| + histogram_tester_.ExpectBucketCount(
|
| + page_load_metrics::internal::kErrorEvents,
|
| + page_load_metrics::ERR_BAD_TIMING_IPC_INVALID_TIMING, 1);
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + page_load_metrics::internal::kPageLoadTimingStatus, 1);
|
| + histogram_tester_.ExpectBucketCount(
|
| + page_load_metrics::internal::kPageLoadTimingStatus,
|
| + page_load_metrics::internal::INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT, 1);
|
| +}
|
| +
|
| +// Test code that aborts provisional navigations.
|
| +// TODO(csharrison): Move these to unit tests once the navigation API in content
|
| +// properly calls NavigationHandle/NavigationThrottle methods.
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + AbortNewNavigation) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + GURL url(embedded_test_server()->GetURL("/title1.html"));
|
| + chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
|
| + content::TestNavigationManager manager(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), url);
|
| +
|
| + chrome::Navigate(¶ms);
|
| + EXPECT_TRUE(manager.WaitForRequestStart());
|
| +
|
| + 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);
|
| + chrome::Navigate(¶ms2);
|
| +
|
| + manager2.WaitForNavigationFinished();
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramAbortNewNavigationBeforeCommit, 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, AbortReload) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + GURL url(embedded_test_server()->GetURL("/title1.html"));
|
| + chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
|
| + content::TestNavigationManager manager(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), url);
|
| +
|
| + chrome::Navigate(¶ms);
|
| + EXPECT_TRUE(manager.WaitForRequestStart());
|
| +
|
| + chrome::NavigateParams params2(browser(), url, ui::PAGE_TRANSITION_RELOAD);
|
| + content::TestNavigationManager manager2(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), url);
|
| + chrome::Navigate(¶ms2);
|
| +
|
| + manager2.WaitForNavigationFinished();
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramAbortReloadBeforeCommit, 1);
|
| +}
|
| +
|
| +// TODO(crbug.com/675061): Flaky on Win7 dbg.
|
| +#if defined(OS_WIN)
|
| +#define MAYBE_AbortClose DISABLED_AbortClose
|
| +#else
|
| +#define MAYBE_AbortClose AbortClose
|
| +#endif
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + MAYBE_AbortClose) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + GURL url(embedded_test_server()->GetURL("/title1.html"));
|
| + chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
|
| + content::TestNavigationManager manager(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), url);
|
| +
|
| + chrome::Navigate(¶ms);
|
| + EXPECT_TRUE(manager.WaitForRequestStart());
|
| +
|
| + browser()->tab_strip_model()->GetActiveWebContents()->Close();
|
| +
|
| + manager.WaitForNavigationFinished();
|
| +
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramAbortCloseBeforeCommit,
|
| + 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, AbortMultiple) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + GURL url(embedded_test_server()->GetURL("/title1.html"));
|
| + chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
|
| + content::TestNavigationManager manager(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), url);
|
| +
|
| + chrome::Navigate(¶ms);
|
| + EXPECT_TRUE(manager.WaitForRequestStart());
|
| +
|
| + GURL url2(embedded_test_server()->GetURL("/title2.html"));
|
| + chrome::NavigateParams params2(browser(), url2, ui::PAGE_TRANSITION_TYPED);
|
| + content::TestNavigationManager manager2(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), url2);
|
| + chrome::Navigate(¶ms2);
|
| +
|
| + EXPECT_TRUE(manager2.WaitForRequestStart());
|
| + manager.WaitForNavigationFinished();
|
| +
|
| + 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);
|
| + chrome::Navigate(¶ms3);
|
| +
|
| + EXPECT_TRUE(manager3.WaitForRequestStart());
|
| + manager2.WaitForNavigationFinished();
|
| +
|
| + manager3.WaitForNavigationFinished();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramAbortNewNavigationBeforeCommit, 2);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NoAbortMetricsOnClientRedirect) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + GURL first_url(embedded_test_server()->GetURL("/title1.html"));
|
| + ui_test_utils::NavigateToURL(browser(), first_url);
|
| +
|
| + GURL second_url(embedded_test_server()->GetURL("/title2.html"));
|
| + chrome::NavigateParams params(browser(), second_url,
|
| + ui::PAGE_TRANSITION_LINK);
|
| + content::TestNavigationManager manager(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), second_url);
|
| + chrome::Navigate(¶ms);
|
| + EXPECT_TRUE(manager.WaitForRequestStart());
|
| +
|
| + {
|
| + content::TestNavigationManager reload_manager(
|
| + browser()->tab_strip_model()->GetActiveWebContents(), first_url);
|
| + EXPECT_TRUE(content::ExecuteScript(
|
| + browser()->tab_strip_model()->GetActiveWebContents(),
|
| + "window.location.reload();"));
|
| + }
|
| +
|
| + manager.WaitForNavigationFinished();
|
| +
|
| + EXPECT_TRUE(histogram_tester_
|
| + .GetTotalCountsForPrefix("PageLoad.Experimental.AbortTiming.")
|
| + .empty());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + FirstMeaningfulPaintRecorded) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| +
|
| + // 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);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstMeaningfulPaint,
|
| + 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramParseStartToFirstMeaningfulPaint, 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + FirstMeaningfulPaintNotRecorded) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| +
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/page_with_active_connections.html"));
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + // Navigate away before a FMP is reported.
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectUniqueSample(
|
| + internal::kHistogramFirstMeaningfulPaintStatus,
|
| + internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, 1);
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstMeaningfulPaint,
|
| + 0);
|
| + histogram_tester_.ExpectTotalCount(
|
| + internal::kHistogramParseStartToFirstMeaningfulPaint, 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NoStatePrefetchObserverCacheable) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/title1.html"));
|
| +
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 0);
|
| + histogram_tester_.ExpectTotalCount(
|
| + "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
|
| + NoStatePrefetchObserverNoStore) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
|
| +
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + embedded_test_server()->GetURL("/nostore.html"));
|
| +
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(
|
| + "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 0);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, CSSTiming) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
|
| + fcp_observer->AddMatchingFields(
|
| + PageLoadTimingObserver::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
|
| + // unset here.
|
| + ui_test_utils::NavigateToURL(
|
| + browser(),
|
| + embedded_test_server()->GetURL("/page_load_metrics/page_with_css.html"));
|
| + NavigateToUntrackedUrl();
|
| + fcp_observer->WaitForTimingUpdated();
|
| +
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint,
|
| + 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + "PageLoad.CSSTiming.Parse.BeforeFirstContentfulPaint", 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + "PageLoad.CSSTiming.Update.BeforeFirstContentfulPaint", 1);
|
| + histogram_tester_.ExpectTotalCount(
|
| + "PageLoad.CSSTiming.ParseAndUpdate.BeforeFirstContentfulPaint", 1);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, PayloadSize) {
|
| + ASSERT_TRUE(
|
| + base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
|
| + ASSERT_TRUE(embedded_test_server()->Start());
|
| +
|
| + ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(
|
| + "/page_load_metrics/large.html"));
|
| + NavigateToUntrackedUrl();
|
| +
|
| + histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1);
|
| +
|
| + // Verify that there is a single sample recorded in the 10kB bucket (the size
|
| + // of the main HTML response).
|
| + histogram_tester_.ExpectBucketCount(internal::kHistogramTotalBytes, 10, 1);
|
| +}
|
|
|