Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: chrome/browser/page_load_metrics/page_load_metrics_mojofication_browsertest.cc

Issue 2823523003: [Page Load Metrics] PageLoadMetrics Mojofication. (Closed)
Patch Set: update Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/files/scoped_temp_dir.h"
6 #include "base/macros.h"
7 #include "base/test/histogram_tester.h"
8 #include "base/test/scoped_feature_list.h"
9 #include "base/time/time.h"
10 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
11 #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_ob server.h"
12 #include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_obse rver.h"
13 #include "chrome/browser/page_load_metrics/observers/document_write_page_load_me trics_observer.h"
14 #include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load _metrics_observer.h"
15 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
16 #include "chrome/browser/prerender/prerender_histograms.h"
17 #include "chrome/browser/prerender/prerender_origin.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_navigator_params.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_features.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/common/url_constants.h"
25 #include "chrome/test/base/in_process_browser_test.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "components/prefs/pref_service.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/render_process_host.h"
30 #include "content/public/browser/render_view_host.h"
31 #include "content/public/test/browser_test_utils.h"
32 #include "content/public/test/download_test_observer.h"
33 #include "content/public/test/web_contents_binding_set_test_binder.h"
34 #include "mojo/public/cpp/bindings/associated_binding.h"
35 #include "net/http/failing_http_transaction_factory.h"
36 #include "net/http/http_cache.h"
37 #include "net/test/embedded_test_server/embedded_test_server.h"
38 #include "net/test/url_request/url_request_failed_job.h"
39 #include "net/url_request/url_request_context.h"
40 #include "net/url_request/url_request_context_getter.h"
41 #include "testing/gmock/include/gmock/gmock.h"
42
43 namespace {
44
45 void FailAllNetworkTransactions(net::URLRequestContextGetter* getter) {
46 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
47 net::HttpCache* cache(
48 getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
49 DCHECK(cache);
50 std::unique_ptr<net::FailingHttpTransactionFactory> factory(
51 new net::FailingHttpTransactionFactory(cache->GetSession(),
52 net::ERR_FAILED));
53 // Throw away old version; since this is a browser test, there is no
54 // need to restore the old state.
55 cache->SetHttpNetworkTransactionFactoryForTesting(std::move(factory));
56 }
57
58 // Wait until we dispatch PageLoadTiming through UpdateTiming.
59 // matching a PageLoadTiming. See WaitForTimingUpdated for details.
60 class PageLoadTimingObserver {
61 public:
62 // A bitvector to express which timing fields to match on.
63 enum ExpectedTimingFields {
64 FIRST_PAINT = 1 << 0,
65 FIRST_CONTENTFUL_PAINT = 1 << 1,
66 STYLE_UPDATE_BEFORE_FCP = 1 << 2
67 };
68
69 PageLoadTimingObserver() {
70 // Roundtrip to the IO thread, to ensure that the filter is properly
71 // installed.
72 content::BrowserThread::PostTaskAndReply(
73 content::BrowserThread::IO, FROM_HERE, base::Bind(&base::DoNothing),
74 base::Bind(&PageLoadTimingObserver::Quit, base::Unretained(this)));
75 run_loop_.reset(new base::RunLoop());
76 run_loop_->Run();
77 run_loop_.reset(nullptr);
78 }
79
80 ~PageLoadTimingObserver() {}
81
82 // Add the given timing fields to the set of fields to match on.
83 void AddMatchingFields(ExpectedTimingFields fields) {
84 matching_fields_ |= fields;
85 }
86
87 // Instructs observer to also watch for |count|
88 // WebLoadingBehaviorDocumentWriteBlockReload events.
89 void MatchDocumentWriteBlockReload(int count) {
90 match_document_write_block_reload_ = count;
91 }
92
93 // Waits for a PageLoadTiming that matches the fields set by
94 // Waits for a TimingUpdated IPC that matches the fields set by
95 // UpdateTiming to end this wait.
96 void WaitForTimingUpdated() {
97 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
98 if (matched_timing_update_)
99 return;
100
101 run_loop_.reset(new base::RunLoop());
102 run_loop_->Run();
103 run_loop_.reset(nullptr);
104 }
105
106 void UpdateTiming(const page_load_metrics::PageLoadTiming& timing,
107 const page_load_metrics::PageLoadMetadata& metadata) {
108 if (match_document_write_block_reload_ > 0 &&
109 metadata.behavior_flags &
110 blink::WebLoadingBehaviorFlag::
111 kWebLoadingBehaviorDocumentWriteBlockReload) {
112 --match_document_write_block_reload_;
113 }
114
115 if (match_document_write_block_reload_ > 0) {
116 return;
117 }
118
119 if ((!(matching_fields_ & FIRST_PAINT) ||
120 timing.paint_timing.first_paint) &&
121 (!(matching_fields_ & FIRST_CONTENTFUL_PAINT) ||
122 timing.paint_timing.first_contentful_paint) &&
123 (!(matching_fields_ & STYLE_UPDATE_BEFORE_FCP) ||
124 timing.style_sheet_timing.update_style_duration_before_fcp)) {
125 // Ensure that any other handlers of this message, for example the real
126 // PageLoadMetric observers, get a chance to handle this message before
127 // this waiter unblocks.
128 content::BrowserThread::PostTask(
129 content::BrowserThread::IO, FROM_HERE,
130 base::Bind(&PageLoadTimingObserver::BounceTimingUpdate,
131 base::Unretained(this)));
132 }
133 }
134
135 private:
136 void BounceTimingUpdate() {
137 content::BrowserThread::PostTask(
138 content::BrowserThread::UI, FROM_HERE,
139 base::Bind(&PageLoadTimingObserver::SetTimingUpdatedAndQuit,
140 base::Unretained(this)));
141 }
142
143 void Quit() {
144 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
145 if (run_loop_)
146 run_loop_->Quit();
147 }
148
149 void SetTimingUpdatedAndQuit() {
150 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
151 matched_timing_update_ = true;
152 Quit();
153 }
154
155 std::unique_ptr<base::RunLoop> run_loop_;
156 int matching_fields_ = 0; // A bitvector composed from ExpectedTimingFields.
157 bool matched_timing_update_ = false;
158 int match_document_write_block_reload_ = 0;
159 };
160
161 } // namespace
162
163 namespace page_load_metrics {
164
165 class FakePageLoadMetrics : public mojom::PageLoadMetrics {
166 public:
167 explicit FakePageLoadMetrics(content::RenderFrameHost* render_frame_host) {
168 metrics_observer_ = content::WebContentsUserData<
169 page_load_metrics::MetricsWebContentsObserver>::
170 FromWebContents(
171 content::WebContents::FromRenderFrameHost(render_frame_host));
172 metrics_observer_->page_load_metrics_binding_for_testing()
173 .SetCurrentTargetFrameForTesting(render_frame_host);
174 }
175
176 ~FakePageLoadMetrics() override {}
177
178 void AddObserver(PageLoadTimingObserver* observer) {
179 observers_.push_back(base::WrapUnique(observer));
180 }
181
182 private:
183 void UpdateTiming(const PageLoadTiming& timing,
184 const PageLoadMetadata& metadata) override {
185 metrics_observer_->UpdateTiming(timing, metadata);
186 for (auto& observer : observers_) {
187 observer->UpdateTiming(timing, metadata);
188 }
189 }
190
191 MetricsWebContentsObserver* metrics_observer_;
192 std::vector<std::unique_ptr<PageLoadTimingObserver>> observers_;
193 };
194
195 } // namespace page_load_metrics
196
197 namespace {
198
199 class FakePageLoadMetricsBinder
200 : public content::WebContentsBindingSetTestBinder<
201 page_load_metrics::mojom::PageLoadMetrics> {
202 public:
203 FakePageLoadMetricsBinder(
204 page_load_metrics::mojom::PageLoadMetrics* page_load_metrics)
205 : page_load_metrics_(page_load_metrics) {}
206 ~FakePageLoadMetricsBinder() override {}
207
208 void BindRequest(content::RenderFrameHost* frame_host,
209 page_load_metrics::mojom::PageLoadMetricsAssociatedRequest
210 request) override {
211 bindings_.AddBinding(page_load_metrics_, std::move(request), frame_host);
212 }
213
214 private:
215 page_load_metrics::mojom::PageLoadMetrics* page_load_metrics_;
216 mojo::AssociatedBindingSet<page_load_metrics::mojom::PageLoadMetrics,
217 content::RenderFrameHost*>
218 bindings_;
219
220 DISALLOW_COPY_AND_ASSIGN(FakePageLoadMetricsBinder);
221 };
222
223 } // namespace
224
225 class PageLoadMetricsMojoficationBrowserTest : public InProcessBrowserTest {
226 public:
227 PageLoadMetricsMojoficationBrowserTest() {}
228 ~PageLoadMetricsMojoficationBrowserTest() override {}
229
230 void SetUpCommandLine(base::CommandLine* command_line) override {
231 // We need to set the feature state before the render process is created,
232 // in order for it to inherit the feature state from the browser process.
233 // SetUp() runs too early, and SetUpOnMainThread() runs too late.
234 scoped_feature_list_.InitAndEnableFeature(
235 features::kPageLoadMetricsMojofication);
236 }
237
238 protected:
239 void NavigateToUntrackedUrl() {
240 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
241 }
242
243 bool NoPageLoadMetricsRecorded() {
244 // Determine whether any 'public' page load metrics are recorded. We exclude
245 // 'internal' metrics as these may be recorded for debugging purposes.
246 size_t total_pageload_histograms =
247 histogram_tester_.GetTotalCountsForPrefix("PageLoad.").size();
248 size_t total_internal_histograms =
249 histogram_tester_.GetTotalCountsForPrefix("PageLoad.Internal.").size();
250 DCHECK_GE(total_pageload_histograms, total_internal_histograms);
251 return total_pageload_histograms - total_internal_histograms == 0;
252 }
253
254 PageLoadTimingObserver* CreatePageLoadTimingObserver() {
255 if (!fake_page_load_metrics_) {
256 content::WebContents* web_contents =
257 browser()->tab_strip_model()->GetActiveWebContents();
258 fake_page_load_metrics_.reset(new page_load_metrics::FakePageLoadMetrics(
259 web_contents->GetMainFrame()));
260 content::WebContentsBindingSet::GetForWebContents<
261 page_load_metrics::mojom::PageLoadMetrics>(web_contents)
262 ->SetBinderForTesting(base::MakeUnique<FakePageLoadMetricsBinder>(
263 fake_page_load_metrics_.get()));
264 }
265 PageLoadTimingObserver* observer = new PageLoadTimingObserver();
266 fake_page_load_metrics_->AddObserver(observer);
267 return observer;
268 }
269
270 base::test::ScopedFeatureList scoped_feature_list_;
271 std::unique_ptr<page_load_metrics::FakePageLoadMetrics>
272 fake_page_load_metrics_;
273 base::HistogramTester histogram_tester_;
274
275 private:
276 DISALLOW_COPY_AND_ASSIGN(PageLoadMetricsMojoficationBrowserTest);
277 };
278
279 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, NoNavigation) {
280 ASSERT_TRUE(
281 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
282 ASSERT_TRUE(embedded_test_server()->Start());
283 EXPECT_TRUE(NoPageLoadMetricsRecorded());
284 }
285
286 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, NewPage) {
287 ASSERT_TRUE(
288 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
289 ASSERT_TRUE(embedded_test_server()->Start());
290
291 ui_test_utils::NavigateToURL(browser(),
292 embedded_test_server()->GetURL("/title1.html"));
293 NavigateToUntrackedUrl();
294
295 histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1);
296 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1);
297 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1);
298 histogram_tester_.ExpectTotalCount(internal::kHistogramParseDuration, 1);
299 histogram_tester_.ExpectTotalCount(
300 internal::kHistogramParseBlockedOnScriptLoad, 1);
301 histogram_tester_.ExpectTotalCount(
302 internal::kHistogramParseBlockedOnScriptExecution, 1);
303 histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1);
304 histogram_tester_.ExpectTotalCount(
305 internal::kHistogramPageTimingForegroundDuration, 1);
306
307 // Verify that NoPageLoadMetricsRecorded returns false when PageLoad metrics
308 // have been recorded.
309 EXPECT_FALSE(NoPageLoadMetricsRecorded());
310 }
311
312 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
313 SameDocumentNavigation) {
314 ASSERT_TRUE(
315 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
316 ASSERT_TRUE(embedded_test_server()->Start());
317
318 ui_test_utils::NavigateToURL(browser(),
319 embedded_test_server()->GetURL("/title1.html"));
320 ui_test_utils::NavigateToURL(
321 browser(), embedded_test_server()->GetURL("/title1.html#hash"));
322 NavigateToUntrackedUrl();
323
324 histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 1);
325 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 1);
326 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 1);
327 }
328
329 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
330 SameUrlNavigation) {
331 ASSERT_TRUE(
332 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
333 ASSERT_TRUE(embedded_test_server()->Start());
334
335 ui_test_utils::NavigateToURL(browser(),
336 embedded_test_server()->GetURL("/title1.html"));
337 ui_test_utils::NavigateToURL(browser(),
338 embedded_test_server()->GetURL("/title1.html"));
339 NavigateToUntrackedUrl();
340
341 // We expect one histogram sample for each navigation to title1.html.
342 histogram_tester_.ExpectTotalCount(internal::kHistogramDomContentLoaded, 2);
343 histogram_tester_.ExpectTotalCount(internal::kHistogramLoad, 2);
344 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 2);
345 }
346
347 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
348 NonHtmlMainResource) {
349 ASSERT_TRUE(
350 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
351 ASSERT_TRUE(embedded_test_server()->Start());
352
353 ui_test_utils::NavigateToURL(browser(),
354 embedded_test_server()->GetURL("/circle.svg"));
355 NavigateToUntrackedUrl();
356 EXPECT_TRUE(NoPageLoadMetricsRecorded());
357 }
358
359 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
360 NonHttpOrHttpsUrl) {
361 ASSERT_TRUE(
362 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
363 ASSERT_TRUE(embedded_test_server()->Start());
364
365 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL));
366 NavigateToUntrackedUrl();
367 EXPECT_TRUE(NoPageLoadMetricsRecorded());
368 }
369
370 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, HttpErrorPage) {
371 ASSERT_TRUE(
372 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
373 ASSERT_TRUE(embedded_test_server()->Start());
374
375 ui_test_utils::NavigateToURL(
376 browser(), embedded_test_server()->GetURL("/page_load_metrics/404.html"));
377 NavigateToUntrackedUrl();
378 EXPECT_TRUE(NoPageLoadMetricsRecorded());
379 }
380
381 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
382 ChromeErrorPage) {
383 ASSERT_TRUE(
384 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
385 ASSERT_TRUE(embedded_test_server()->Start());
386
387 // Configure the network stack to fail all attempted loads with a network
388 // error, which will cause Chrome to display an error page.
389 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
390 browser()->profile()->GetRequestContext();
391 content::BrowserThread::PostTask(
392 content::BrowserThread::IO, FROM_HERE,
393 base::Bind(&FailAllNetworkTransactions,
394 base::RetainedRef(url_request_context_getter)));
395
396 ui_test_utils::NavigateToURL(browser(),
397 embedded_test_server()->GetURL("/title1.html"));
398 NavigateToUntrackedUrl();
399 EXPECT_TRUE(NoPageLoadMetricsRecorded());
400 }
401
402 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, Ignore204Pages) {
403 ASSERT_TRUE(
404 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
405 ASSERT_TRUE(embedded_test_server()->Start());
406
407 ui_test_utils::NavigateToURL(browser(),
408 embedded_test_server()->GetURL("/page204.html"));
409 NavigateToUntrackedUrl();
410 EXPECT_TRUE(NoPageLoadMetricsRecorded());
411 }
412
413 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
414 IgnoreDownloads) {
415 ASSERT_TRUE(
416 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
417 ASSERT_TRUE(embedded_test_server()->Start());
418
419 base::ScopedTempDir downloads_directory;
420 ASSERT_TRUE(downloads_directory.CreateUniqueTempDir());
421 browser()->profile()->GetPrefs()->SetFilePath(
422 prefs::kDownloadDefaultDirectory, downloads_directory.GetPath());
423 content::DownloadTestObserverTerminal downloads_observer(
424 content::BrowserContext::GetDownloadManager(browser()->profile()),
425 1, // == wait_count (only waiting for "download-test3.gif").
426 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
427
428 ui_test_utils::NavigateToURL(
429 browser(), embedded_test_server()->GetURL("/download-test3.gif"));
430 downloads_observer.WaitForFinished();
431
432 NavigateToUntrackedUrl();
433 EXPECT_TRUE(NoPageLoadMetricsRecorded());
434 }
435
436 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
437 PreloadDocumentWrite) {
438 ASSERT_TRUE(
439 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
440 ASSERT_TRUE(embedded_test_server()->Start());
441
442 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
443 fcp_observer->AddMatchingFields(
444 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
445
446 ui_test_utils::NavigateToURL(
447 browser(), embedded_test_server()->GetURL(
448 "/page_load_metrics/document_write_external_script.html"));
449 fcp_observer->WaitForTimingUpdated();
450
451 histogram_tester_.ExpectTotalCount(
452 internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 1);
453 }
454
455 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
456 NoPreloadDocumentWrite) {
457 ASSERT_TRUE(
458 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
459 ASSERT_TRUE(embedded_test_server()->Start());
460
461 ui_test_utils::NavigateToURL(
462 browser(), embedded_test_server()->GetURL(
463 "/page_load_metrics/document_write_no_script.html"));
464 NavigateToUntrackedUrl();
465
466 histogram_tester_.ExpectTotalCount(
467 internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0);
468 }
469
470 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
471 NoDocumentWrite) {
472 ASSERT_TRUE(
473 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
474 ASSERT_TRUE(embedded_test_server()->Start());
475
476 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
477 fcp_observer->AddMatchingFields(
478 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
479
480 ui_test_utils::NavigateToURL(browser(),
481 embedded_test_server()->GetURL("/title1.html"));
482 fcp_observer->WaitForTimingUpdated();
483
484 histogram_tester_.ExpectTotalCount(
485 internal::kHistogramDocWriteParseStartToFirstContentfulPaint, 0);
486 histogram_tester_.ExpectTotalCount(
487 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
488 histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
489 }
490
491 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
492 DocumentWriteBlock) {
493 ASSERT_TRUE(
494 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
495 ASSERT_TRUE(embedded_test_server()->Start());
496
497 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
498 fcp_observer->AddMatchingFields(
499 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
500
501 ui_test_utils::NavigateToURL(
502 browser(), embedded_test_server()->GetURL(
503 "/page_load_metrics/document_write_script_block.html"));
504 fcp_observer->WaitForTimingUpdated();
505
506 histogram_tester_.ExpectTotalCount(
507 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
508 histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1);
509 }
510
511 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
512 DocumentWriteReload) {
513 ASSERT_TRUE(
514 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
515 ASSERT_TRUE(embedded_test_server()->Start());
516
517 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
518 fcp_observer->AddMatchingFields(
519 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
520 PageLoadTimingObserver* reload_observer = CreatePageLoadTimingObserver();
521 reload_observer->MatchDocumentWriteBlockReload(2);
522
523 ui_test_utils::NavigateToURL(
524 browser(), embedded_test_server()->GetURL(
525 "/page_load_metrics/document_write_script_block.html"));
526
527 // Reload should not log the histogram as the script is not blocked.
528 ui_test_utils::NavigateToURL(
529 browser(), embedded_test_server()->GetURL(
530 "/page_load_metrics/document_write_script_block.html"));
531
532 ui_test_utils::NavigateToURL(
533 browser(), embedded_test_server()->GetURL(
534 "/page_load_metrics/document_write_script_block.html"));
535
536 histogram_tester_.ExpectTotalCount(
537 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
538
539 fcp_observer->WaitForTimingUpdated();
540 reload_observer->WaitForTimingUpdated();
541
542 histogram_tester_.ExpectTotalCount(
543 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 1);
544
545 histogram_tester_.ExpectTotalCount(
546 internal::kHistogramDocWriteBlockReloadCount, 2);
547 histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 1);
548 }
549
550 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
551 DocumentWriteAsync) {
552 ASSERT_TRUE(
553 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
554 ASSERT_TRUE(embedded_test_server()->Start());
555
556 ui_test_utils::NavigateToURL(
557 browser(), embedded_test_server()->GetURL(
558 "/page_load_metrics/document_write_script_async.html"));
559 NavigateToUntrackedUrl();
560
561 histogram_tester_.ExpectTotalCount(
562 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
563 histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
564 }
565
566 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
567 DocumentWriteSameDomain) {
568 ASSERT_TRUE(
569 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
570 ASSERT_TRUE(embedded_test_server()->Start());
571
572 ui_test_utils::NavigateToURL(
573 browser(), embedded_test_server()->GetURL(
574 "/page_load_metrics/document_write_external_script.html"));
575 NavigateToUntrackedUrl();
576
577 histogram_tester_.ExpectTotalCount(
578 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
579 histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
580 }
581
582 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
583 NoDocumentWriteScript) {
584 ASSERT_TRUE(
585 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
586 ASSERT_TRUE(embedded_test_server()->Start());
587
588 ui_test_utils::NavigateToURL(
589 browser(), embedded_test_server()->GetURL(
590 "/page_load_metrics/document_write_no_script.html"));
591 NavigateToUntrackedUrl();
592
593 histogram_tester_.ExpectTotalCount(
594 internal::kHistogramDocWriteBlockParseStartToFirstContentfulPaint, 0);
595 histogram_tester_.ExpectTotalCount(internal::kHistogramDocWriteBlockCount, 0);
596 }
597
598 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, BadXhtml) {
599 ASSERT_TRUE(
600 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
601 ASSERT_TRUE(embedded_test_server()->Start());
602
603 PageLoadTimingObserver* timing_observer = CreatePageLoadTimingObserver();
604 timing_observer->AddMatchingFields(PageLoadTimingObserver::FIRST_PAINT);
605
606 // When an XHTML page contains invalid XML, it causes a paint of the error
607 // message without a layout. Page load metrics currently treats this as an
608 // error. Eventually, we'll fix this by special casing the handling of
609 // documents with non-well-formed XML on the blink side. See crbug.com/627607
610 // for more.
611 ui_test_utils::NavigateToURL(
612 browser(),
613 embedded_test_server()->GetURL("/page_load_metrics/badxml.xhtml"));
614
615 timing_observer->WaitForTimingUpdated();
616
617 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstLayout, 0);
618 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstPaint, 0);
619 histogram_tester_.ExpectTotalCount(page_load_metrics::internal::kErrorEvents,
620 1);
621 histogram_tester_.ExpectBucketCount(
622 page_load_metrics::internal::kErrorEvents,
623 page_load_metrics::ERR_BAD_TIMING_IPC_INVALID_TIMING, 1);
624
625 histogram_tester_.ExpectTotalCount(
626 page_load_metrics::internal::kPageLoadTimingStatus, 1);
627 histogram_tester_.ExpectBucketCount(
628 page_load_metrics::internal::kPageLoadTimingStatus,
629 page_load_metrics::internal::INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT, 1);
630 }
631
632 // Test code that aborts provisional navigations.
633 // TODO(csharrison): Move these to unit tests once the navigation API in content
634 // properly calls NavigationHandle/NavigationThrottle methods.
635 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
636 AbortNewNavigation) {
637 ASSERT_TRUE(
638 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
639 ASSERT_TRUE(embedded_test_server()->Start());
640
641 GURL url(embedded_test_server()->GetURL("/title1.html"));
642 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
643 content::TestNavigationManager manager(
644 browser()->tab_strip_model()->GetActiveWebContents(), url);
645
646 chrome::Navigate(&params);
647 EXPECT_TRUE(manager.WaitForRequestStart());
648
649 GURL url2(embedded_test_server()->GetURL("/title2.html"));
650 chrome::NavigateParams params2(browser(), url2,
651 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
652 content::TestNavigationManager manager2(
653 browser()->tab_strip_model()->GetActiveWebContents(), url2);
654 chrome::Navigate(&params2);
655
656 manager2.WaitForNavigationFinished();
657 histogram_tester_.ExpectTotalCount(
658 internal::kHistogramAbortNewNavigationBeforeCommit, 1);
659 }
660
661 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, AbortReload) {
662 ASSERT_TRUE(
663 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
664 ASSERT_TRUE(embedded_test_server()->Start());
665
666 GURL url(embedded_test_server()->GetURL("/title1.html"));
667 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
668 content::TestNavigationManager manager(
669 browser()->tab_strip_model()->GetActiveWebContents(), url);
670
671 chrome::Navigate(&params);
672 EXPECT_TRUE(manager.WaitForRequestStart());
673
674 chrome::NavigateParams params2(browser(), url, ui::PAGE_TRANSITION_RELOAD);
675 content::TestNavigationManager manager2(
676 browser()->tab_strip_model()->GetActiveWebContents(), url);
677 chrome::Navigate(&params2);
678
679 manager2.WaitForNavigationFinished();
680 histogram_tester_.ExpectTotalCount(
681 internal::kHistogramAbortReloadBeforeCommit, 1);
682 }
683
684 // TODO(crbug.com/675061): Flaky on Win7 dbg.
685 #if defined(OS_WIN)
686 #define MAYBE_AbortClose DISABLED_AbortClose
687 #else
688 #define MAYBE_AbortClose AbortClose
689 #endif
690 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
691 MAYBE_AbortClose) {
692 ASSERT_TRUE(
693 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
694 ASSERT_TRUE(embedded_test_server()->Start());
695
696 GURL url(embedded_test_server()->GetURL("/title1.html"));
697 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
698 content::TestNavigationManager manager(
699 browser()->tab_strip_model()->GetActiveWebContents(), url);
700
701 chrome::Navigate(&params);
702 EXPECT_TRUE(manager.WaitForRequestStart());
703
704 browser()->tab_strip_model()->GetActiveWebContents()->Close();
705
706 manager.WaitForNavigationFinished();
707
708 histogram_tester_.ExpectTotalCount(internal::kHistogramAbortCloseBeforeCommit,
709 1);
710 }
711
712 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, AbortMultiple) {
713 ASSERT_TRUE(
714 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
715 ASSERT_TRUE(embedded_test_server()->Start());
716
717 GURL url(embedded_test_server()->GetURL("/title1.html"));
718 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
719 content::TestNavigationManager manager(
720 browser()->tab_strip_model()->GetActiveWebContents(), url);
721
722 chrome::Navigate(&params);
723 EXPECT_TRUE(manager.WaitForRequestStart());
724
725 GURL url2(embedded_test_server()->GetURL("/title2.html"));
726 chrome::NavigateParams params2(browser(), url2, ui::PAGE_TRANSITION_TYPED);
727 content::TestNavigationManager manager2(
728 browser()->tab_strip_model()->GetActiveWebContents(), url2);
729 chrome::Navigate(&params2);
730
731 EXPECT_TRUE(manager2.WaitForRequestStart());
732 manager.WaitForNavigationFinished();
733
734 GURL url3(embedded_test_server()->GetURL("/title3.html"));
735 chrome::NavigateParams params3(browser(), url3, ui::PAGE_TRANSITION_TYPED);
736 content::TestNavigationManager manager3(
737 browser()->tab_strip_model()->GetActiveWebContents(), url3);
738 chrome::Navigate(&params3);
739
740 EXPECT_TRUE(manager3.WaitForRequestStart());
741 manager2.WaitForNavigationFinished();
742
743 manager3.WaitForNavigationFinished();
744
745 histogram_tester_.ExpectTotalCount(
746 internal::kHistogramAbortNewNavigationBeforeCommit, 2);
747 }
748
749 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
750 NoAbortMetricsOnClientRedirect) {
751 ASSERT_TRUE(
752 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
753 ASSERT_TRUE(embedded_test_server()->Start());
754
755 GURL first_url(embedded_test_server()->GetURL("/title1.html"));
756 ui_test_utils::NavigateToURL(browser(), first_url);
757
758 GURL second_url(embedded_test_server()->GetURL("/title2.html"));
759 chrome::NavigateParams params(browser(), second_url,
760 ui::PAGE_TRANSITION_LINK);
761 content::TestNavigationManager manager(
762 browser()->tab_strip_model()->GetActiveWebContents(), second_url);
763 chrome::Navigate(&params);
764 EXPECT_TRUE(manager.WaitForRequestStart());
765
766 {
767 content::TestNavigationManager reload_manager(
768 browser()->tab_strip_model()->GetActiveWebContents(), first_url);
769 EXPECT_TRUE(content::ExecuteScript(
770 browser()->tab_strip_model()->GetActiveWebContents(),
771 "window.location.reload();"));
772 }
773
774 manager.WaitForNavigationFinished();
775
776 EXPECT_TRUE(histogram_tester_
777 .GetTotalCountsForPrefix("PageLoad.Experimental.AbortTiming.")
778 .empty());
779 }
780
781 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
782 FirstMeaningfulPaintRecorded) {
783 ASSERT_TRUE(
784 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
785 ASSERT_TRUE(embedded_test_server()->Start());
786
787 ui_test_utils::NavigateToURL(browser(),
788 embedded_test_server()->GetURL("/title1.html"));
789
790 // Wait until the renderer finishes observing layouts.
791 const int kNetworkIdleTime = 3000;
792 const int kMargin = 500;
793 const std::string javascript = base::StringPrintf(
794 "setTimeout(() => window.domAutomationController.send(true), %d)",
795 kNetworkIdleTime + kMargin);
796 bool result;
797 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
798 browser()->tab_strip_model()->GetActiveWebContents(), javascript,
799 &result));
800 EXPECT_TRUE(result);
801
802 NavigateToUntrackedUrl();
803 histogram_tester_.ExpectUniqueSample(
804 internal::kHistogramFirstMeaningfulPaintStatus,
805 internal::FIRST_MEANINGFUL_PAINT_RECORDED, 1);
806 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstMeaningfulPaint,
807 1);
808 histogram_tester_.ExpectTotalCount(
809 internal::kHistogramParseStartToFirstMeaningfulPaint, 1);
810 }
811
812 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
813 FirstMeaningfulPaintNotRecorded) {
814 ASSERT_TRUE(
815 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
816 ASSERT_TRUE(embedded_test_server()->Start());
817
818 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
819 fcp_observer->AddMatchingFields(
820 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
821
822 ui_test_utils::NavigateToURL(
823 browser(), embedded_test_server()->GetURL(
824 "/page_load_metrics/page_with_active_connections.html"));
825 fcp_observer->WaitForTimingUpdated();
826
827 // Navigate away before a FMP is reported.
828 NavigateToUntrackedUrl();
829
830 histogram_tester_.ExpectUniqueSample(
831 internal::kHistogramFirstMeaningfulPaintStatus,
832 internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, 1);
833 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstMeaningfulPaint,
834 0);
835 histogram_tester_.ExpectTotalCount(
836 internal::kHistogramParseStartToFirstMeaningfulPaint, 0);
837 }
838
839 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
840 NoStatePrefetchObserverCacheable) {
841 ASSERT_TRUE(
842 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
843 ASSERT_TRUE(embedded_test_server()->Start());
844
845 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
846 fcp_observer->AddMatchingFields(
847 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
848
849 ui_test_utils::NavigateToURL(browser(),
850 embedded_test_server()->GetURL("/title1.html"));
851
852 fcp_observer->WaitForTimingUpdated();
853
854 histogram_tester_.ExpectTotalCount(
855 "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 0);
856 histogram_tester_.ExpectTotalCount(
857 "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 1);
858 }
859
860 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest,
861 NoStatePrefetchObserverNoStore) {
862 ASSERT_TRUE(
863 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
864 ASSERT_TRUE(embedded_test_server()->Start());
865
866 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
867 fcp_observer->AddMatchingFields(
868 PageLoadTimingObserver::FIRST_CONTENTFUL_PAINT);
869
870 ui_test_utils::NavigateToURL(browser(),
871 embedded_test_server()->GetURL("/nostore.html"));
872
873 fcp_observer->WaitForTimingUpdated();
874
875 histogram_tester_.ExpectTotalCount(
876 "Prerender.none_PrefetchTTFCP.Reference.NoStore.Visible", 1);
877 histogram_tester_.ExpectTotalCount(
878 "Prerender.none_PrefetchTTFCP.Reference.Cacheable.Visible", 0);
879 }
880
881 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, CSSTiming) {
882 ASSERT_TRUE(
883 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
884 ASSERT_TRUE(embedded_test_server()->Start());
885
886 PageLoadTimingObserver* fcp_observer = CreatePageLoadTimingObserver();
887 fcp_observer->AddMatchingFields(
888 PageLoadTimingObserver::STYLE_UPDATE_BEFORE_FCP);
889
890 // Careful: Blink code clamps timestamps to 5us, so any CSS parsing we do here
891 // must take >> 5us, otherwise we'll log 0 for the value and it will remain
892 // unset here.
893 ui_test_utils::NavigateToURL(
894 browser(),
895 embedded_test_server()->GetURL("/page_load_metrics/page_with_css.html"));
896 NavigateToUntrackedUrl();
897 fcp_observer->WaitForTimingUpdated();
898
899 histogram_tester_.ExpectTotalCount(internal::kHistogramFirstContentfulPaint,
900 1);
901 histogram_tester_.ExpectTotalCount(
902 "PageLoad.CSSTiming.Parse.BeforeFirstContentfulPaint", 1);
903 histogram_tester_.ExpectTotalCount(
904 "PageLoad.CSSTiming.Update.BeforeFirstContentfulPaint", 1);
905 histogram_tester_.ExpectTotalCount(
906 "PageLoad.CSSTiming.ParseAndUpdate.BeforeFirstContentfulPaint", 1);
907 }
908
909 IN_PROC_BROWSER_TEST_F(PageLoadMetricsMojoficationBrowserTest, PayloadSize) {
910 ASSERT_TRUE(
911 base::FeatureList::IsEnabled(features::kPageLoadMetricsMojofication));
912 ASSERT_TRUE(embedded_test_server()->Start());
913
914 ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(
915 "/page_load_metrics/large.html"));
916 NavigateToUntrackedUrl();
917
918 histogram_tester_.ExpectTotalCount(internal::kHistogramTotalBytes, 1);
919
920 // Verify that there is a single sample recorded in the 10kB bucket (the size
921 // of the main HTML response).
922 histogram_tester_.ExpectBucketCount(internal::kHistogramTotalBytes, 10, 1);
923 }
OLDNEW
« no previous file with comments | « chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc ('k') | chrome/common/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698