| // Copyright 2017 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 "core/loader/InteractiveDetector.h" |
| |
| #include "core/dom/Document.h" |
| #include "core/paint/FirstMeaningfulPaintDetector.h" |
| #include "core/testing/DummyPageHolder.h" |
| #include "core/testing/PageTestBase.h" |
| #include "platform/CrossThreadFunctional.h" |
| #include "platform/scheduler/renderer/renderer_scheduler_impl.h" |
| #include "platform/testing/TestingPlatformSupportWithMockScheduler.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace blink { |
| |
| class NetworkActivityCheckerForTest |
| : public InteractiveDetector::NetworkActivityChecker { |
| public: |
| NetworkActivityCheckerForTest(Document* document) |
| : InteractiveDetector::NetworkActivityChecker(document) {} |
| |
| virtual void SetActiveConnections(int active_connections) { |
| active_connections_ = active_connections; |
| }; |
| int GetActiveConnections() override; |
| |
| private: |
| int active_connections_ = 0; |
| }; |
| |
| int NetworkActivityCheckerForTest::GetActiveConnections() { |
| return active_connections_; |
| } |
| |
| struct TaskTiming { |
| double start; |
| double end; |
| TaskTiming(double start, double end) : start(start), end(end) {} |
| }; |
| |
| class InteractiveDetectorTest : public ::testing::Test { |
| public: |
| InteractiveDetectorTest() { |
| platform_->AdvanceClockSeconds(1); |
| dummy_page_holder_ = DummyPageHolder::Create(); |
| |
| Document* document = &dummy_page_holder_->GetDocument(); |
| |
| detector_ = new InteractiveDetector( |
| *document, new NetworkActivityCheckerForTest(document)); |
| |
| // By this time, the DummyPageHolder has created an InteractiveDetector, and |
| // sent DOMContentLoadedEnd. We overwrite it with our new |
| // InteractiveDetector, which won't have received any timestamps. |
| Supplement<Document>::ProvideTo( |
| *document, InteractiveDetector::SupplementName(), detector_.Get()); |
| |
| // Ensure the document is using the injected InteractiveDetector. |
| DCHECK_EQ(detector_, InteractiveDetector::From(*document)); |
| } |
| |
| // Public because it's executed on a task queue. |
| void DummyTaskWithDuration(double duration_seconds) { |
| platform_->AdvanceClockSeconds(duration_seconds); |
| dummy_task_end_time_ = CurrentTimeTicksInSeconds(); |
| } |
| |
| protected: |
| InteractiveDetector* GetDetector() { return detector_; } |
| |
| double GetDummyTaskEndTime() { return dummy_task_end_time_; } |
| |
| NetworkActivityCheckerForTest* GetNetworkActivityChecker() { |
| // We know in this test context that network_activity_checker_ is an |
| // instance of NetworkActivityCheckerForTest, so this static_cast is safe. |
| return static_cast<NetworkActivityCheckerForTest*>( |
| detector_->network_activity_checker_.get()); |
| } |
| |
| void SimulateNavigationStart(double nav_start_time) { |
| RunTillTimestamp(nav_start_time); |
| detector_->SetNavigationStartTime(nav_start_time); |
| } |
| |
| void SimulateLongTask(double start, double end) { |
| CHECK(end - start >= 0.05); |
| RunTillTimestamp(end); |
| detector_->OnLongTaskDetected(start, end); |
| } |
| |
| void SimulateDOMContentLoadedEnd(double dcl_time) { |
| RunTillTimestamp(dcl_time); |
| detector_->OnDomContentLoadedEnd(dcl_time); |
| } |
| |
| void SimulateFMPDetected(double fmp_time, double detection_time) { |
| RunTillTimestamp(detection_time); |
| detector_->OnFirstMeaningfulPaintDetected( |
| fmp_time, FirstMeaningfulPaintDetector::kNoUserInput); |
| } |
| |
| void SimulateInteractiveInvalidatingInput(double timestamp) { |
| RunTillTimestamp(timestamp); |
| detector_->OnInvalidatingInputEvent(timestamp); |
| } |
| |
| void RunTillTimestamp(double target_time) { |
| double current_time = CurrentTimeTicksInSeconds(); |
| platform_->RunForPeriodSeconds(std::max(0.0, target_time - current_time)); |
| } |
| |
| int GetActiveConnections() { |
| return GetNetworkActivityChecker()->GetActiveConnections(); |
| } |
| |
| void SetActiveConnections(int active_connections) { |
| GetNetworkActivityChecker()->SetActiveConnections(active_connections); |
| } |
| |
| void SimulateResourceLoadBegin(double load_begin_time) { |
| RunTillTimestamp(load_begin_time); |
| detector_->OnResourceLoadBegin(load_begin_time); |
| // ActiveConnections is incremented after detector runs OnResourceLoadBegin; |
| SetActiveConnections(GetActiveConnections() + 1); |
| } |
| |
| void SimulateResourceLoadEnd(double load_finish_time) { |
| RunTillTimestamp(load_finish_time); |
| int active_connections = GetActiveConnections(); |
| SetActiveConnections(active_connections - 1); |
| detector_->OnResourceLoadEnd(load_finish_time); |
| } |
| |
| double GetInteractiveTime() { return detector_->GetInteractiveTime(); } |
| |
| ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> |
| platform_; |
| |
| private: |
| Persistent<InteractiveDetector> detector_; |
| std::unique_ptr<DummyPageHolder> dummy_page_holder_; |
| double dummy_task_end_time_ = 0.0; |
| }; |
| |
| // Note: The tests currently assume kTimeToInteractiveWindowSeconds is 5 |
| // seconds. The window size is unlikely to change, and this makes the test |
| // scenarios significantly easier to write. |
| |
| // Note: Some of the tests are named W_X_Y_Z, where W, X, Y, Z can any of the |
| // following events: |
| // FMP: First Meaningful Paint |
| // DCL: DomContentLoadedEnd |
| // FmpDetect: Detection of FMP. FMP is not detected in realtime. |
| // LT: Long Task |
| // The name shows the ordering of these events in the test. |
| |
| TEST_F(InteractiveDetectorTest, FMP_DCL_FmpDetect) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 3.0); |
| SimulateFMPDetected(/* fmp_time */ t0 + 5.0, /* detection_time */ t0 + 7.0); |
| // Run until 5 seconds after FMP. |
| RunTillTimestamp((t0 + 5.0) + 5.0 + 0.1); |
| // Reached TTI at FMP. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 5.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, DCL_FMP_FmpDetect) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 5.0); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 7.0); |
| // Run until 5 seconds after FMP. |
| RunTillTimestamp((t0 + 3.0) + 5.0 + 0.1); |
| // Reached TTI at DCL. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 5.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, InstantDetectionAtFmpDetectIfPossible) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 5.0); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 10.0); |
| // Although we just detected FMP, the FMP timestamp is more than |
| // kTimeToInteractiveWindowSeconds earlier. We should instantaneously |
| // detect that we reached TTI at DCL. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 5.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, FmpDetectFiresAfterLateLongTask) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 3.0); |
| SimulateLongTask(t0 + 9.0, t0 + 9.1); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 10.0); |
| // There is a 5 second quiet window after fmp_time - the long task is 6s |
| // seconds after fmp_time. We should instantly detect we reached TTI at FMP. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 3.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, FMP_FmpDetect_DCL) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 5.0); |
| SimulateDOMContentLoadedEnd(t0 + 9.0); |
| // TTI reached at DCL. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 9.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, LongTaskBeforeFMPDoesNotAffectTTI) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 3.0); |
| SimulateLongTask(t0 + 5.1, t0 + 5.2); |
| SimulateFMPDetected(/* fmp_time */ t0 + 8.0, /* detection_time */ t0 + 9.0); |
| // Run till 5 seconds after FMP. |
| RunTillTimestamp((t0 + 8.0) + 5.0 + 0.1); |
| // TTI reached at FMP. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 8.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, DCLDoesNotResetTimer) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateLongTask(t0 + 5.0, t0 + 5.1); |
| SimulateDOMContentLoadedEnd(t0 + 8.0); |
| // Run till 5 seconds after long task end. |
| RunTillTimestamp((t0 + 5.1) + 5.0 + 0.1); |
| // TTI Reached at DCL. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 8.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, DCL_FMP_FmpDetect_LT) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 3.0); |
| SimulateFMPDetected(/* fmp_time */ t0 + 4.0, /* detection_time */ t0 + 5.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); |
| // Run till 5 seconds after long task end. |
| RunTillTimestamp((t0 + 7.1) + 5.0 + 0.1); |
| // TTI reached at long task end. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 7.1); |
| } |
| |
| TEST_F(InteractiveDetectorTest, DCL_FMP_LT_FmpDetect) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 3.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 5.0); |
| // Run till 5 seconds after long task end. |
| RunTillTimestamp((t0 + 7.1) + 5.0 + 0.1); |
| // TTI reached at long task end. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 7.1); |
| } |
| |
| TEST_F(InteractiveDetectorTest, FMP_FmpDetect_LT_DCL) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); |
| SimulateDOMContentLoadedEnd(t0 + 8.0); |
| // Run till 5 seconds after long task end. |
| RunTillTimestamp((t0 + 7.1) + 5.0 + 0.1); |
| // TTI reached at DCL. Note that we do not need to wait for DCL + 5 seconds. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 8.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, DclIsMoreThan5sAfterFMP) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); // Long task 1. |
| SimulateDOMContentLoadedEnd(t0 + 10.0); |
| // Have not reached TTI yet. |
| EXPECT_EQ(GetInteractiveTime(), 0.0); |
| SimulateLongTask(t0 + 11.0, t0 + 11.1); // Long task 2. |
| // Run till long task 2 end + 5 seconds. |
| RunTillTimestamp((t0 + 11.1) + 5.0 + 0.1); |
| // TTI reached at long task 2 end. |
| EXPECT_EQ(GetInteractiveTime(), (t0 + 11.1)); |
| } |
| |
| TEST_F(InteractiveDetectorTest, NetworkBusyBlocksTTIEvenWhenMainThreadQuiet) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateResourceLoadBegin(t0 + 3.4); // Request 2 start. |
| SimulateResourceLoadBegin(t0 + 3.5); // Request 3 start. Network busy. |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); // Long task 1. |
| SimulateResourceLoadEnd(t0 + 12.2); // Network quiet. |
| // Network busy kept page from reaching TTI.. |
| EXPECT_EQ(GetInteractiveTime(), 0.0); |
| SimulateLongTask(t0 + 13.0, t0 + 13.1); // Long task 2. |
| // Run till 5 seconds after long task 2 end. |
| RunTillTimestamp((t0 + 13.1) + 5.0 + 0.1); |
| EXPECT_EQ(GetInteractiveTime(), (t0 + 13.1)); |
| } |
| |
| TEST_F(InteractiveDetectorTest, LongEnoughQuietWindowBetweenFMPAndFmpDetect) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateLongTask(t0 + 2.1, t0 + 2.2); // Long task 1. |
| SimulateLongTask(t0 + 8.2, t0 + 8.3); // Long task 2. |
| SimulateResourceLoadBegin(t0 + 8.4); // Request 2 start. |
| SimulateResourceLoadBegin(t0 + 8.5); // Request 3 start. Network busy. |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 10.0); |
| // Even though network is currently busy and we have long task finishing |
| // recently, we should be able to detect that the page already achieved TTI at |
| // FMP. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 3.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, NetworkBusyEndIsNotTTI) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateResourceLoadBegin(t0 + 3.4); // Request 2 start. |
| SimulateResourceLoadBegin(t0 + 3.5); // Request 3 start. Network busy. |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); // Long task 1. |
| SimulateLongTask(t0 + 13.0, t0 + 13.1); // Long task 2. |
| SimulateResourceLoadEnd(t0 + 14.0); // Network quiet. |
| // Run till 5 seconds after network busy end. |
| RunTillTimestamp((t0 + 14.0) + 5.0 + 0.1); |
| // TTI reached at long task 2 end, NOT at network busy end. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 13.1); |
| } |
| |
| TEST_F(InteractiveDetectorTest, LateLongTaskWithLateFMPDetection) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateResourceLoadBegin(t0 + 3.4); // Request 2 start. |
| SimulateResourceLoadBegin(t0 + 3.5); // Request 3 start. Network busy. |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); // Long task 1. |
| SimulateResourceLoadEnd(t0 + 8.0); // Network quiet. |
| SimulateLongTask(t0 + 14.0, t0 + 14.1); // Long task 2. |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 20.0); |
| // TTI reached at long task 1 end, NOT at long task 2 end. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 7.1); |
| } |
| |
| TEST_F(InteractiveDetectorTest, IntermittentNetworkBusyBlocksTTI) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); // Long task 1. |
| SimulateResourceLoadBegin(t0 + 7.9); // Active connections: 2 |
| // Network busy start. |
| SimulateResourceLoadBegin(t0 + 8.0); // Active connections: 3. |
| // Network busy end. |
| SimulateResourceLoadEnd(t0 + 8.5); // Active connections: 2. |
| // Network busy start. |
| SimulateResourceLoadBegin(t0 + 11.0); // Active connections: 3. |
| // Network busy end. |
| SimulateResourceLoadEnd(t0 + 12.0); // Active connections: 2. |
| SimulateLongTask(t0 + 14.0, t0 + 14.1); // Long task 2. |
| // Run till 5 seconds after long task 2 end. |
| RunTillTimestamp((t0 + 14.1) + 5.0 + 0.1); |
| // TTI reached at long task 2 end. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 14.1); |
| } |
| |
| TEST_F(InteractiveDetectorTest, InvalidatingUserInput) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0); |
| SimulateInteractiveInvalidatingInput(t0 + 5.0); |
| SimulateLongTask(t0 + 7.0, t0 + 7.1); // Long task 1. |
| // Run till 5 seconds after long task 2 end. |
| RunTillTimestamp((t0 + 7.1) + 5.0 + 0.1); |
| // We still detect interactive time on the blink side even if there is an |
| // invalidating user input. Page Load Metrics filters out this value in the |
| // browser process for UMA reporting. |
| EXPECT_EQ(GetInteractiveTime(), t0 + 7.1); |
| EXPECT_EQ(GetDetector()->GetFirstInvalidatingInputTime(), t0 + 5.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, InvalidatedFMP) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| SimulateNavigationStart(t0); |
| // Network is forever quiet for this test. |
| SetActiveConnections(1); |
| SimulateInteractiveInvalidatingInput(t0 + 1.0); |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| RunTillTimestamp(t0 + 4.0); // FMP Detection time. |
| GetDetector()->OnFirstMeaningfulPaintDetected( |
| t0 + 3.0, FirstMeaningfulPaintDetector::kHadUserInput); |
| // Run till 5 seconds after FMP. |
| RunTillTimestamp((t0 + 3.0) + 5.0 + 0.1); |
| // Since FMP was invalidated, we do not have TTI or TTI Detection Time. |
| EXPECT_EQ(GetInteractiveTime(), 0.0); |
| EXPECT_EQ(GetDetector()->GetInteractiveDetectionTime(), 0.0); |
| // Invalidating input timestamp is available. |
| EXPECT_EQ(GetDetector()->GetFirstInvalidatingInputTime(), t0 + 1.0); |
| } |
| |
| TEST_F(InteractiveDetectorTest, TaskLongerThan5sBlocksTTI) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| GetDetector()->SetNavigationStartTime(t0); |
| |
| SimulateDOMContentLoadedEnd(t0 + 2.0); |
| SimulateFMPDetected(t0 + 3.0, t0 + 4.0); |
| |
| // Post a task with 6 seconds duration. |
| PostCrossThreadTask( |
| *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE, |
| CrossThreadBind(&InteractiveDetectorTest::DummyTaskWithDuration, |
| CrossThreadUnretained(this), 6.0)); |
| |
| platform_->RunUntilIdle(); |
| |
| // We should be able to detect TTI 5s after the end of long task. |
| platform_->RunForPeriodSeconds(5.1); |
| EXPECT_EQ(GetDetector()->GetInteractiveTime(), GetDummyTaskEndTime()); |
| } |
| |
| TEST_F(InteractiveDetectorTest, LongTaskAfterTTIDoesNothing) { |
| double t0 = CurrentTimeTicksInSeconds(); |
| GetDetector()->SetNavigationStartTime(t0); |
| |
| SimulateDOMContentLoadedEnd(2.0); |
| SimulateFMPDetected(t0 + 3.0, t0 + 4.0); |
| |
| // Long task 1. |
| PostCrossThreadTask( |
| *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE, |
| CrossThreadBind(&InteractiveDetectorTest::DummyTaskWithDuration, |
| CrossThreadUnretained(this), 0.1)); |
| |
| platform_->RunUntilIdle(); |
| |
| double long_task_1_end_time = GetDummyTaskEndTime(); |
| // We should be able to detect TTI 5s after the end of long task. |
| platform_->RunForPeriodSeconds(5.1); |
| EXPECT_EQ(GetDetector()->GetInteractiveTime(), long_task_1_end_time); |
| |
| // Long task 2. |
| PostCrossThreadTask( |
| *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE, |
| CrossThreadBind(&InteractiveDetectorTest::DummyTaskWithDuration, |
| CrossThreadUnretained(this), 0.1)); |
| |
| platform_->RunUntilIdle(); |
| // Wait 5 seconds to see if TTI time changes. |
| platform_->RunForPeriodSeconds(5.1); |
| // TTI time should not change. |
| EXPECT_EQ(GetDetector()->GetInteractiveTime(), long_task_1_end_time); |
| } |
| |
| } // namespace blink |