| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/predictors/loading_data_collector.h" | 5 #include "chrome/browser/predictors/loading_data_collector.h" |
| 6 | 6 |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
| 13 #include "chrome/browser/history/history_service_factory.h" | 13 #include "chrome/browser/history/history_service_factory.h" |
| 14 #include "chrome/browser/predictors/loading_predictor_config.h" |
| 14 #include "chrome/browser/predictors/loading_test_util.h" | 15 #include "chrome/browser/predictors/loading_test_util.h" |
| 15 #include "chrome/test/base/testing_profile.h" | 16 #include "chrome/test/base/testing_profile.h" |
| 16 #include "content/public/test/test_browser_thread_bundle.h" | 17 #include "content/public/test/test_browser_thread_bundle.h" |
| 17 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" |
| 18 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_job.h" | 20 #include "net/url_request/url_request_job.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 23 |
| 23 using testing::StrictMock; | 24 using testing::StrictMock; |
| 24 | 25 |
| 25 namespace predictors { | 26 namespace predictors { |
| 26 | 27 |
| 27 class LoadingDataCollectorTest : public testing::Test { | 28 class LoadingDataCollectorTest : public testing::Test { |
| 28 public: | 29 public: |
| 30 LoadingDataCollectorTest() : profile_(new TestingProfile()) { |
| 31 LoadingPredictorConfig config; |
| 32 PopulateTestConfig(&config); |
| 33 mock_predictor_ = |
| 34 base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>( |
| 35 config, profile_.get()), |
| 36 collector_ = base::MakeUnique<LoadingDataCollector>(mock_predictor_.get(), |
| 37 nullptr, config); |
| 38 } |
| 39 |
| 29 void SetUp() override { | 40 void SetUp() override { |
| 41 base::RunLoop loop; |
| 42 loop.RunUntilIdle(); // Runs the DB lookup. |
| 43 |
| 30 url_request_job_factory_.Reset(); | 44 url_request_job_factory_.Reset(); |
| 31 url_request_context_.set_job_factory(&url_request_job_factory_); | 45 url_request_context_.set_job_factory(&url_request_job_factory_); |
| 32 } | 46 } |
| 33 | 47 |
| 34 protected: | 48 protected: |
| 35 content::TestBrowserThreadBundle thread_bundle_; | 49 content::TestBrowserThreadBundle thread_bundle_; |
| 50 std::unique_ptr<TestingProfile> profile_; |
| 36 net::TestURLRequestContext url_request_context_; | 51 net::TestURLRequestContext url_request_context_; |
| 37 MockURLRequestJobFactory url_request_job_factory_; | 52 MockURLRequestJobFactory url_request_job_factory_; |
| 53 |
| 54 std::unique_ptr<StrictMock<MockResourcePrefetchPredictor>> mock_predictor_; |
| 55 std::unique_ptr<LoadingDataCollector> collector_; |
| 38 }; | 56 }; |
| 39 | 57 |
| 40 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { | 58 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { |
| 41 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 59 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| 42 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); | 60 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); |
| 43 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 61 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| 44 content::RESOURCE_TYPE_STYLESHEET, "")); | 62 content::RESOURCE_TYPE_STYLESHEET, "")); |
| 45 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( | 63 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( |
| 46 content::RESOURCE_TYPE_WORKER, "text/css")); | 64 content::RESOURCE_TYPE_WORKER, "text/css")); |
| 47 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( | 65 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 prefetch_unknown_font_request.get())); | 238 prefetch_unknown_font_request.get())); |
| 221 | 239 |
| 222 // Not main frame. | 240 // Not main frame. |
| 223 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( | 241 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( |
| 224 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), | 242 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), |
| 225 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); | 243 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); |
| 226 EXPECT_FALSE( | 244 EXPECT_FALSE( |
| 227 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); | 245 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); |
| 228 } | 246 } |
| 229 | 247 |
| 248 // Single navigation that will be recorded. Will check for duplicate |
| 249 // resources and also for number of resources saved. |
| 250 TEST_F(LoadingDataCollectorTest, SimpleNavigation) { |
| 251 URLRequestSummary main_frame = |
| 252 CreateURLRequestSummary(1, "http://www.google.com"); |
| 253 collector_->RecordURLRequest(main_frame); |
| 254 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 255 |
| 256 std::vector<URLRequestSummary> resources; |
| 257 resources.push_back(CreateURLRequestSummary( |
| 258 1, "http://www.google.com", "http://google.com/style1.css", |
| 259 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false)); |
| 260 collector_->RecordURLResponse(resources.back()); |
| 261 resources.push_back(CreateURLRequestSummary( |
| 262 1, "http://www.google.com", "http://google.com/script1.js", |
| 263 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| 264 collector_->RecordURLResponse(resources.back()); |
| 265 resources.push_back(CreateURLRequestSummary( |
| 266 1, "http://www.google.com", "http://google.com/script2.js", |
| 267 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| 268 collector_->RecordURLResponse(resources.back()); |
| 269 resources.push_back(CreateURLRequestSummary( |
| 270 1, "http://www.google.com", "http://google.com/script1.js", |
| 271 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true)); |
| 272 collector_->RecordURLResponse(resources.back()); |
| 273 resources.push_back(CreateURLRequestSummary( |
| 274 1, "http://www.google.com", "http://google.com/image1.png", |
| 275 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| 276 collector_->RecordURLResponse(resources.back()); |
| 277 resources.push_back(CreateURLRequestSummary( |
| 278 1, "http://www.google.com", "http://google.com/image2.png", |
| 279 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| 280 collector_->RecordURLResponse(resources.back()); |
| 281 resources.push_back(CreateURLRequestSummary( |
| 282 1, "http://www.google.com", "http://google.com/style2.css", |
| 283 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true)); |
| 284 collector_->RecordURLResponse(resources.back()); |
| 285 |
| 286 auto no_store = CreateURLRequestSummary( |
| 287 1, "http://www.google.com", |
| 288 "http://static.google.com/style2-no-store.css", |
| 289 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| 290 no_store.is_no_store = true; |
| 291 collector_->RecordURLResponse(no_store); |
| 292 |
| 293 auto redirected = CreateURLRequestSummary( |
| 294 1, "http://www.google.com", "http://reader.google.com/style.css", |
| 295 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| 296 redirected.redirect_url = GURL("http://dev.null.google.com/style.css"); |
| 297 |
| 298 collector_->RecordURLRedirect(redirected); |
| 299 redirected.is_no_store = true; |
| 300 redirected.request_url = redirected.redirect_url; |
| 301 redirected.redirect_url = GURL(); |
| 302 |
| 303 collector_->RecordURLResponse(redirected); |
| 304 |
| 305 EXPECT_CALL( |
| 306 *mock_predictor_, |
| 307 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| 308 "http://www.google.com", "http://www.google.com", resources)))); |
| 309 |
| 310 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| 311 } |
| 312 |
| 313 TEST_F(LoadingDataCollectorTest, SimpleRedirect) { |
| 314 URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); |
| 315 collector_->RecordURLRequest(fb1); |
| 316 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 317 |
| 318 URLRequestSummary fb2 = CreateRedirectRequestSummary( |
| 319 1, "http://fb.com/google", "http://facebook.com/google"); |
| 320 collector_->RecordURLRedirect(fb2); |
| 321 URLRequestSummary fb3 = CreateRedirectRequestSummary( |
| 322 1, "http://facebook.com/google", "https://facebook.com/google"); |
| 323 collector_->RecordURLRedirect(fb3); |
| 324 NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google"); |
| 325 |
| 326 EXPECT_CALL( |
| 327 *mock_predictor_, |
| 328 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| 329 "https://facebook.com/google", "http://fb.com/google", |
| 330 std::vector<URLRequestSummary>())))); |
| 331 |
| 332 collector_->RecordMainFrameLoadComplete(fb_end); |
| 333 } |
| 334 |
| 335 TEST_F(LoadingDataCollectorTest, OnMainFrameRequest) { |
| 336 URLRequestSummary summary1 = CreateURLRequestSummary( |
| 337 1, "http://www.google.com", "http://www.google.com", |
| 338 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 339 URLRequestSummary summary2 = CreateURLRequestSummary( |
| 340 2, "http://www.google.com", "http://www.google.com", |
| 341 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 342 URLRequestSummary summary3 = CreateURLRequestSummary( |
| 343 3, "http://www.yahoo.com", "http://www.yahoo.com", |
| 344 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 345 |
| 346 collector_->RecordURLRequest(summary1); |
| 347 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 348 collector_->RecordURLRequest(summary2); |
| 349 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| 350 collector_->RecordURLRequest(summary3); |
| 351 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 352 |
| 353 // Insert another with same navigation id. It should replace. |
| 354 URLRequestSummary summary4 = CreateURLRequestSummary( |
| 355 1, "http://www.nike.com", "http://www.nike.com", |
| 356 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 357 URLRequestSummary summary5 = CreateURLRequestSummary( |
| 358 2, "http://www.google.com", "http://www.google.com", |
| 359 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 360 |
| 361 collector_->RecordURLRequest(summary4); |
| 362 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 363 |
| 364 // Change this creation time so that it will go away on the next insert. |
| 365 summary5.navigation_id.creation_time = |
| 366 base::TimeTicks::Now() - base::TimeDelta::FromDays(1); |
| 367 collector_->RecordURLRequest(summary5); |
| 368 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 369 |
| 370 URLRequestSummary summary6 = CreateURLRequestSummary( |
| 371 4, "http://www.shoes.com", "http://www.shoes.com", |
| 372 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 373 collector_->RecordURLRequest(summary6); |
| 374 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 375 |
| 376 EXPECT_TRUE(collector_->inflight_navigations_.find(summary3.navigation_id) != |
| 377 collector_->inflight_navigations_.end()); |
| 378 EXPECT_TRUE(collector_->inflight_navigations_.find(summary4.navigation_id) != |
| 379 collector_->inflight_navigations_.end()); |
| 380 EXPECT_TRUE(collector_->inflight_navigations_.find(summary6.navigation_id) != |
| 381 collector_->inflight_navigations_.end()); |
| 382 } |
| 383 |
| 384 TEST_F(LoadingDataCollectorTest, OnMainFrameRedirect) { |
| 385 URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com"); |
| 386 |
| 387 URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com"); |
| 388 URLRequestSummary bbc2 = |
| 389 CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com"); |
| 390 NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com"); |
| 391 |
| 392 URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com"); |
| 393 URLRequestSummary youtube2 = CreateRedirectRequestSummary( |
| 394 3, "http://youtube.com", "https://youtube.com"); |
| 395 NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com"); |
| 396 |
| 397 URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com"); |
| 398 URLRequestSummary nyt2 = |
| 399 CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com"); |
| 400 URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com", |
| 401 "http://m.nytimes.com"); |
| 402 NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com"); |
| 403 |
| 404 URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com"); |
| 405 URLRequestSummary fb2 = |
| 406 CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com"); |
| 407 URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com", |
| 408 "https://facebook.com"); |
| 409 URLRequestSummary fb4 = CreateRedirectRequestSummary( |
| 410 5, "https://facebook.com", |
| 411 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); |
| 412 NavigationID fb_end = CreateNavigationID( |
| 413 5, |
| 414 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); |
| 415 |
| 416 // Redirect with empty redirect_url will be deleted. |
| 417 collector_->RecordURLRequest(yahoo); |
| 418 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 419 collector_->OnMainFrameRedirect(yahoo); |
| 420 EXPECT_TRUE(collector_->inflight_navigations_.empty()); |
| 421 |
| 422 // Redirect without previous request works fine. |
| 423 // collector_->RecordURLRequest(bbc1) missing. |
| 424 collector_->OnMainFrameRedirect(bbc2); |
| 425 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 426 EXPECT_EQ(bbc1.navigation_id.main_frame_url, |
| 427 collector_->inflight_navigations_[bbc_end]->initial_url); |
| 428 |
| 429 // http://youtube.com -> https://youtube.com. |
| 430 collector_->RecordURLRequest(youtube1); |
| 431 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| 432 collector_->OnMainFrameRedirect(youtube2); |
| 433 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| 434 EXPECT_EQ(youtube1.navigation_id.main_frame_url, |
| 435 collector_->inflight_navigations_[youtube_end]->initial_url); |
| 436 |
| 437 // http://nyt.com -> http://nytimes.com -> http://m.nytimes.com. |
| 438 collector_->RecordURLRequest(nyt1); |
| 439 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 440 collector_->OnMainFrameRedirect(nyt2); |
| 441 collector_->OnMainFrameRedirect(nyt3); |
| 442 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 443 EXPECT_EQ(nyt1.navigation_id.main_frame_url, |
| 444 collector_->inflight_navigations_[nyt_end]->initial_url); |
| 445 |
| 446 // http://fb.com -> http://facebook.com -> https://facebook.com -> |
| 447 // https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr. |
| 448 collector_->RecordURLRequest(fb1); |
| 449 EXPECT_EQ(4U, collector_->inflight_navigations_.size()); |
| 450 collector_->OnMainFrameRedirect(fb2); |
| 451 collector_->OnMainFrameRedirect(fb3); |
| 452 collector_->OnMainFrameRedirect(fb4); |
| 453 EXPECT_EQ(4U, collector_->inflight_navigations_.size()); |
| 454 EXPECT_EQ(fb1.navigation_id.main_frame_url, |
| 455 collector_->inflight_navigations_[fb_end]->initial_url); |
| 456 } |
| 457 |
| 458 TEST_F(LoadingDataCollectorTest, OnSubresourceResponse) { |
| 459 // If there is no inflight navigation, nothing happens. |
| 460 URLRequestSummary resource1 = CreateURLRequestSummary( |
| 461 1, "http://www.google.com", "http://google.com/style1.css", |
| 462 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| 463 collector_->RecordURLResponse(resource1); |
| 464 EXPECT_TRUE(collector_->inflight_navigations_.empty()); |
| 465 |
| 466 // Add an inflight navigation. |
| 467 URLRequestSummary main_frame1 = CreateURLRequestSummary( |
| 468 1, "http://www.google.com", "http://www.google.com", |
| 469 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 470 collector_->RecordURLRequest(main_frame1); |
| 471 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 472 |
| 473 // Now add a few subresources. |
| 474 URLRequestSummary resource2 = CreateURLRequestSummary( |
| 475 1, "http://www.google.com", "http://google.com/script1.js", |
| 476 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 477 URLRequestSummary resource3 = CreateURLRequestSummary( |
| 478 1, "http://www.google.com", "http://google.com/script2.js", |
| 479 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 480 collector_->RecordURLResponse(resource1); |
| 481 collector_->RecordURLResponse(resource2); |
| 482 collector_->RecordURLResponse(resource3); |
| 483 |
| 484 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 485 EXPECT_EQ(3U, collector_->inflight_navigations_[main_frame1.navigation_id] |
| 486 ->subresource_requests.size()); |
| 487 EXPECT_EQ(resource1, |
| 488 collector_->inflight_navigations_[main_frame1.navigation_id] |
| 489 ->subresource_requests[0]); |
| 490 EXPECT_EQ(resource2, |
| 491 collector_->inflight_navigations_[main_frame1.navigation_id] |
| 492 ->subresource_requests[1]); |
| 493 EXPECT_EQ(resource3, |
| 494 collector_->inflight_navigations_[main_frame1.navigation_id] |
| 495 ->subresource_requests[2]); |
| 496 } |
| 497 |
| 498 TEST_F(LoadingDataCollectorTest, TestRecordFirstContentfulPaint) { |
| 499 auto res1_time = base::TimeTicks::FromInternalValue(1); |
| 500 auto res2_time = base::TimeTicks::FromInternalValue(2); |
| 501 auto fcp_time = base::TimeTicks::FromInternalValue(3); |
| 502 auto res3_time = base::TimeTicks::FromInternalValue(4); |
| 503 |
| 504 URLRequestSummary main_frame = |
| 505 CreateURLRequestSummary(1, "http://www.google.com"); |
| 506 collector_->RecordURLRequest(main_frame); |
| 507 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 508 |
| 509 URLRequestSummary resource1 = CreateURLRequestSummary( |
| 510 1, "http://www.google.com", "http://google.com/style1.css", |
| 511 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| 512 resource1.response_time = res1_time; |
| 513 collector_->RecordURLResponse(resource1); |
| 514 URLRequestSummary resource2 = CreateURLRequestSummary( |
| 515 1, "http://www.google.com", "http://google.com/script1.js", |
| 516 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 517 resource2.response_time = res2_time; |
| 518 collector_->RecordURLResponse(resource2); |
| 519 URLRequestSummary resource3 = CreateURLRequestSummary( |
| 520 1, "http://www.google.com", "http://google.com/script2.js", |
| 521 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 522 resource3.response_time = res3_time; |
| 523 collector_->RecordURLResponse(resource3); |
| 524 |
| 525 collector_->RecordFirstContentfulPaint(main_frame.navigation_id, fcp_time); |
| 526 |
| 527 // Since res3_time is after fcp_time, we expect this field to have been set to |
| 528 // false before RecordPageRequestSummary is called. |
| 529 resource3.before_first_contentful_paint = false; |
| 530 EXPECT_CALL( |
| 531 *mock_predictor_, |
| 532 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| 533 "http://www.google.com", "http://www.google.com", |
| 534 {resource1, resource2, resource3})))); |
| 535 |
| 536 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| 537 } |
| 538 |
| 230 } // namespace predictors | 539 } // namespace predictors |
| OLD | NEW |